SELECT f.name AS ForeignKey,
OBJECT_NAME(f.parent_object_id) AS TableName,
COL_NAME(fc.parent_object_id, fc.parent_column_id) AS ColumnName,
OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName,
COL_NAME(fc.referenced_object_id, fc.referenced_column_id) AS ReferenceColumnName
FROM sys.foreign_keys AS f
INNER JOIN sys.foreign_key_columns AS fc
ON f.OBJECT_ID = fc.constraint_object_id
要生成跨所有外键应用索引的脚本,可以执行以下操作:
SELECT 'CREATE INDEX [IX_' + f.name + '] ON ' + OBJECT_NAME(f.parent_object_id) + '(' + COL_NAME(fc.parent_object_id, fc.parent_column_id) + ')]'
FROM sys.foreign_keys AS f
INNER JOIN sys.foreign_key_columns AS fc
ON f.OBJECT_ID = fc.constraint_object_id
SELECT
*
FROM
(
SELECT TOP 99 PERCENT
f.name AS ForeignKeyName
, s.name
+ '.'
+ OBJECT_NAME(f.parent_object_id)
+ '.'
+ COL_NAME(fc.parent_object_id, fc.parent_column_id)
ParentTable
, referencedSchema.name
+ '.'
+ OBJECT_NAME (f.referenced_object_id)
+ '.'
+ COL_NAME(fc.referenced_object_id, fc.referenced_column_id)
ReferencedTable
, 'CREATE INDEX [IX_' + f.name + ']'
+ ' ON '
+ '[' + referencedSchema.name + ']'
+ '.'
+ '[' + OBJECT_NAME(f.parent_object_id) + ']'
+ '('
+ COL_NAME(fc.parent_object_id, fc.parent_column_id)
+ ')'
CreateIndexSql
FROM
sys.foreign_keys AS f
INNER JOIN sys.foreign_key_columns AS fc ON f.OBJECT_ID = fc.constraint_object_id
inner join sys.schemas s on f.schema_id = s.schema_id
inner join sys.tables referencedTable on f.referenced_object_id = referencedTable.object_id
inner join sys.schemas referencedSchema on referencedTable.schema_id = referencedSchema.schema_id
ORDER BY
2, 3, 1
) a
where a.ParentTable not in (
-- Add any exclusions here so you can forget about them
''
)
基于@toepoke.co.uk答案和SQLShack post here,下面是一个脚本的综合解决方案,用于在FK上创建所有缺少的索引。
CREATE TABLE #TempForeignKeys
(
TableName VARCHAR(100)
,ForeignKeyName VARCHAR(100)
,ObjectID INT
)
--check foreign keys that do not have indexes
INSERT INTO #TempForeignKeys
SELECT OBJ.name, ForKey.name, ForKey.object_id
FROM sys.foreign_keys ForKey
INNER JOIN sys.objects OBJ ON OBJ.object_id = ForKey.parent_object_id
WHERE OBJ.is_ms_shipped = 0
CREATE TABLE #TempIndexedFK
(
ObjectID INT
)
INSERT INTO #TempIndexedFK
SELECT FK.ObjectID
FROM sys.foreign_key_columns ForKeyCol
JOIN sys.index_columns IDXCol ON ForKeyCol.parent_object_id = IDXCol.object_id
JOIN #TempForeignKeys FK ON ForKeyCol.constraint_object_id = FK.ObjectID
WHERE ForKeyCol.parent_column_id = IDXCol.column_id
--SELECT * FROM #TempForeignKeys WHERE ObjectID NOT IN (SELECT ObjectID FROM #TempIndexedFK)
SELECT *
FROM (
SELECT f.name AS ForeignKeyName
,s.name + '.' + OBJECT_NAME(f.parent_object_id) + '.'
+ COL_NAME(fc.parent_object_id, fc.parent_column_id) ParentTable
,referencedSchema.name + '.' + OBJECT_NAME(f.referenced_object_id) + '.'
+ COL_NAME(fc.referenced_object_id, fc.referenced_column_id) ReferencedTable
,'CREATE INDEX [IX_' + f.name + ']' + ' ON ' + '[' + referencedSchema.name + ']' + '.'
+ '[' + OBJECT_NAME(f.parent_object_id) + ']' + '('
+ COL_NAME(fc.parent_object_id, fc.parent_column_id) + ')' CreateIndexSql
FROM sys.foreign_keys AS f
INNER JOIN sys.foreign_key_columns AS fc ON f.object_id = fc.constraint_object_id
INNER JOIN sys.schemas s ON f.schema_id = s.schema_id
INNER JOIN sys.tables referencedTable ON f.referenced_object_id = referencedTable.object_id
INNER JOIN sys.schemas referencedSchema ON referencedTable.schema_id = referencedSchema.schema_id
WHERE f.object_id NOT IN (
SELECT ObjectID FROM #TempIndexedFK
)
) a
ORDER BY 3
DROP TABLE #TempForeignKeys
DROP TABLE #TempIndexedFK
3条答案
按热度按时间aiqt4smr1#
它们是通过T-SQL脚本还是通过设计器创建的并不重要。您的问题有点含糊,因此我不确定您是否也在询问是否可以对所有外键建立索引。但是,如果您是这样,则应在查询中频繁引用的列上创建索引,并且您可以执行以下操作来提高性能:
要通过
T-SQL
创建索引:要获取所有外键的列表:
要生成跨所有外键应用索引的脚本,可以执行以下操作:
http://msdn.microsoft.com/en-us/library/ms188783.aspx
gjmwrych2#
各位干得好,非常乐于助人。
添加一个包含表模式的增强。如果你愿意,你也可以排除FK名称(我倾向于不在小表上添加索引)
nwsw7zdq3#
基于@toepoke.co.uk答案和SQLShack post here,下面是一个脚本的综合解决方案,用于在FK上创建所有缺少的索引。