English 中文(简体)
sql 服务器 : 必要时在外国密钥上创建索引
原标题:sql server : create indexes on foreign keys where necessary

我有许多带有外国密钥的表格,有些有索引,而另一些则没有。所有外国密钥都名为 FKlt@lt;外国密钥 >的名称; ; 外密钥 >的名称; .

是否有良好做法可以创建(或不创建)索引?

最佳回答

不管它们是通过 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" rel="noreferr">http://msdn.microsoft.com/en-us/library/ms188783.aspx

问题回答

大家干得漂亮,很有帮助

添加包含表格公式的增强功能。如果您愿意,也可以排除 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
        
)

依据@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




相关问题
what is wrong with this mysql code

$db_user="root"; $db_host="localhost"; $db_password="root"; $db_name = "fayer"; $conn = mysqli_connect($db_host,$db_user,$db_password,$db_name) or die ("couldn t connect to server"); // perform query ...

Users asking for denormalized database

I am in the early stages of developing a database-driven system and the largest part of the system revolves around an inheritance type of relationship. There is a parent entity with about 10 columns ...

Easiest way to deal with sample data in Java web apps?

I m writing a Java web app in my free time to learn more about development. I m using the Stripes framework and eventually intend to use hibernate and MySQL For the moment, whilst creating the pages ...

join across databases with nhibernate

I am trying to join two tables that reside in two different databases. Every time, I try to join I get the following error: An association from the table xxx refers to an unmapped class. If the ...

How can I know if such value exists in database? (ADO.NET)

For example, I have a table, and there is a column named Tags . I want to know if value programming exists in this column. How can I do this in ADO.NET? I did this: OleDbCommand cmd = new ...

Convert date to string upon saving a doctrine record

I m trying to migrate one of my PHP projects to Doctrine. I ve never used it before so there are a few things I don t understand. In my current code, I have a class similar to this: class ...

热门标签