Sql server 如何索引MS SQL中的所有外键?

Sql server 如何索引MS SQL中的所有外键?,sql-server,indexing,foreign-keys,Sql Server,Indexing,Foreign Keys,我们有很多表和外键的大型MS SQL数据库。由于性能原因,我们需要索引表中的所有外键,并且我们正试图避免手动执行。有没有什么方法可以让MS SQL自动或使用一些工具来完成 使用的MS SQL server是MS SQL server 2008 R2 非常感谢。我会引导您避免尝试自动执行此操作,并鼓励您检查您的系统Google missing index DMVs SQL 2005或更高版本,以获得良好的开端,并创建适当的索引。如果您尝试自动执行此操作,则可能会引入以下问题: 在具有低优先级的列上

我们有很多表和外键的大型MS SQL数据库。由于性能原因,我们需要索引表中的所有外键,并且我们正试图避免手动执行。有没有什么方法可以让MS SQL自动或使用一些工具来完成

使用的MS SQL server是MS SQL server 2008 R2


非常感谢。

我会引导您避免尝试自动执行此操作,并鼓励您检查您的系统Google missing index DMVs SQL 2005或更高版本,以获得良好的开端,并创建适当的索引。如果您尝试自动执行此操作,则可能会引入以下问题:

在具有低优先级的列上创建索引 将消耗资源但从未被使用的基数 e、 例如,查找的外键 具有少量可能值的表

引入书签查找是因为 您创建的索引可能有 受益于包括额外的 列


我并不是说外键不应该被索引,只是在创建这些索引时应该考虑一些问题。

我会引导您避免尝试自动执行此操作,并鼓励您检查您的系统Google missing index DMVs SQL 2005或更高版本,以获得一个良好的开端,并创建适当的索引。如果您尝试自动执行此操作,则可能会引入以下问题:

在具有低优先级的列上创建索引 将消耗资源但从未被使用的基数 e、 例如,查找的外键 具有少量可能值的表

引入书签查找是因为 您创建的索引可能有 受益于包括额外的 列


我不是说不应该为外键编制索引,只是在创建这些索引时应该考虑一些问题。

这将允许查找所有FK及其相关列。若有人愿意,他们可以编写一个脚本来测试所涉及的表的基数并生成索引

Select rc.constraint_name, table_name,column_name 
from 
    information_schema.REFERENTIAL_CONSTRAINTS rc
    INNER JOIN information_schema.CONSTRAINT_COLUMN_USAGE usage
    on rc.constraint_name = usage.constraint_name

这将允许查找所有FK及其关联列。若有人愿意,他们可以编写一个脚本来测试所涉及的表的基数并生成索引

Select rc.constraint_name, table_name,column_name 
from 
    information_schema.REFERENTIAL_CONSTRAINTS rc
    INNER JOIN information_schema.CONSTRAINT_COLUMN_USAGE usage
    on rc.constraint_name = usage.constraint_name

下面的脚本应该有帮助:

declare @schemaName varchar(128)
declare @tableName varchar(128)
declare @columnName varchar(128)

declare @refSchemaName varchar(128)
declare @refTableName varchar(128)
declare @refColumnName varchar(128)

declare @sql nvarchar(max)
set @sql = ''

declare cur cursor for
select sch.name as SchemaName, tab.name as TableName, col.name as ColumnName, ref_sch.name as RefSchemaName, ref_tab.name as RefTableName, ref_col.name as RefColumnName
from sys.foreign_keys fk
join sys.foreign_key_columns fkc on fkc.constraint_object_id = fk.object_id
join sys.tables tab on tab.object_id = fkc.parent_object_id
join sys.schemas sch on sch.schema_id = tab.schema_id
join sys.columns col on fkc.parent_column_id = col.column_id and fkc.parent_object_id = col.object_id
join sys.tables ref_tab on ref_tab.object_id = fkc.referenced_object_id
join sys.schemas ref_sch on ref_sch.schema_id = ref_tab.schema_id
join sys.columns ref_col on fkc.referenced_column_id = ref_col.column_id and fkc.referenced_object_id = ref_col.object_id

open cur
fetch next from cur into @schemaName, @tableName, @columnName, @refSchemaName, @refTableName, @refColumnName
while @@FETCH_STATUS = 0
begin
    set @sql = '
    if not exists (SELECT * FROM sys.indexes 
    WHERE name=''IX_' + @schemaName + @tableName + '_' + @columnName + ''' AND object_id = OBJECT_ID(''' + @schemaName + '.' + @tableName + ''')) 
    begin
        CREATE INDEX IX_' + @schemaName + @tableName + '_' + @columnName + ' ON [' + @schemaName + '].[' + @tableName + '] 
        ([' + @columnName + ']) WITH (FILLFACTOR = 80) 
    end'
    --print @sql
    exec sp_executesql @sql
    fetch next from cur into @schemaName, @tableName, @columnName, @refSchemaName, @refTableName, @refColumnName
end

close cur
deallocate cur

选择所有外键后,它将创建名称格式为“IX_SchemaNameMetablename_columnName”和fillfactor=80的索引。

下面的脚本应该有帮助:

declare @schemaName varchar(128)
declare @tableName varchar(128)
declare @columnName varchar(128)

declare @refSchemaName varchar(128)
declare @refTableName varchar(128)
declare @refColumnName varchar(128)

declare @sql nvarchar(max)
set @sql = ''

declare cur cursor for
select sch.name as SchemaName, tab.name as TableName, col.name as ColumnName, ref_sch.name as RefSchemaName, ref_tab.name as RefTableName, ref_col.name as RefColumnName
from sys.foreign_keys fk
join sys.foreign_key_columns fkc on fkc.constraint_object_id = fk.object_id
join sys.tables tab on tab.object_id = fkc.parent_object_id
join sys.schemas sch on sch.schema_id = tab.schema_id
join sys.columns col on fkc.parent_column_id = col.column_id and fkc.parent_object_id = col.object_id
join sys.tables ref_tab on ref_tab.object_id = fkc.referenced_object_id
join sys.schemas ref_sch on ref_sch.schema_id = ref_tab.schema_id
join sys.columns ref_col on fkc.referenced_column_id = ref_col.column_id and fkc.referenced_object_id = ref_col.object_id

open cur
fetch next from cur into @schemaName, @tableName, @columnName, @refSchemaName, @refTableName, @refColumnName
while @@FETCH_STATUS = 0
begin
    set @sql = '
    if not exists (SELECT * FROM sys.indexes 
    WHERE name=''IX_' + @schemaName + @tableName + '_' + @columnName + ''' AND object_id = OBJECT_ID(''' + @schemaName + '.' + @tableName + ''')) 
    begin
        CREATE INDEX IX_' + @schemaName + @tableName + '_' + @columnName + ' ON [' + @schemaName + '].[' + @tableName + '] 
        ([' + @columnName + ']) WITH (FILLFACTOR = 80) 
    end'
    --print @sql
    exec sp_executesql @sql
    fetch next from cur into @schemaName, @tableName, @columnName, @refSchemaName, @refTableName, @refColumnName
end

close cur
deallocate cur

选择所有外键后,它将创建名称格式为“IX_SchemaNameMetablename_columnName”和fillfactor=80的索引。

您可以在数据库中找到所有外键,然后可能通过构造sql语句来编写过程对它们进行索引,以避免手动执行此操作。是否确实要为所有FK列编制索引在所有的桌子上?我建议只有当表中的行数超过几百行时才这样做。否则,可能仍会进行扫描。@Pavanred是正确的。要使用的代码在很大程度上取决于您使用的SQL Server版本;贴出来,有人可能会贴一个例子。谢谢。这是MS SQL Server 2008 R2。为所有fk生成索引您可以在数据库中找到所有外键,然后也许可以编写一个过程,通过构造SQL语句对它们进行索引,以避免手动执行此操作。是否确实要为所有表中的所有fk列编制索引?我建议只有当表中的行数超过几百行时才这样做。否则,可能仍会进行扫描。@Pavanred是正确的。要使用的代码在很大程度上取决于您使用的SQL Server版本;贴出来,有人可能会贴一个例子。谢谢。这是MS SQL Server 2008 R2。为所有fk生成索引感谢您的建议。我们将检查所有索引外键。如果有更多的外键需要索引怎么办?也许将它们全部编入索引然后删除不必要的索引更容易些?谢谢你的建议。我们将检查所有索引外键。如果有更多的外键需要索引怎么办?也许将它们全部编入索引然后删除不必要的索引更容易些?