SQL Server SQL服务器:在需要时创建外键索引

nwlqm0z1  于 2023-02-11  发布在  其他
关注(0)|答案(3)|浏览(133)

我有很多带外键的表,有些有索引,有些没有,所有的外键都命名为FK_<name of the foreign key>,索引命名为IX_<name of the foreign key>
在给定外键的列基数的情况下,是否有一些好的实践来创建(或不创建)索引?可以将其编写为T-SQL命令吗?

aiqt4smr

aiqt4smr1#

它们是通过T-SQL脚本还是通过设计器创建的并不重要。您的问题有点含糊,因此我不确定您是否也在询问是否可以对所有外键建立索引。但是,如果您是这样,则应在查询中频繁引用的列上创建索引,并且您可以执行以下操作来提高性能:

  • 运行数据库优化向导,该向导将提供改进摘要并推荐索引。
  • 为所有外键建立索引并运行执行计划(查看查询的执行速度是快还是慢)。

要通过T-SQL创建索引:

CREATE INDEX IX_INDEX_NAME
ON Table (FieldName);

要获取所有外键的列表:

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

http://msdn.microsoft.com/en-us/library/ms188783.aspx

gjmwrych

gjmwrych2#

各位干得好,非常乐于助人。
添加一个包含表模式的增强。如果你愿意,你也可以排除FK名称(我倾向于不在小表上添加索引)

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
      ''
)
nwsw7zdq

nwsw7zdq3#

基于@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

相关问题