Sql server: создавать индексы на внешних ключах, если необходимо

У меня много таблиц с внешними ключами, а у некоторых есть индекс, а у других нет. Все внешние ключи называются FK_<name of the foreign key> с индексами с именем IX_<name of the foreign key>.

Есть ли какие-то хорошие практики, учитывая мощность столбца внешнего ключа, для создания (или нет) индексов? Может ли это быть написано как команды T-SQL?

Ответы

Ответ 1

Не имеет значения, созданы ли они с помощью T-SQL Script или через конструктор. Ваш вопрос немного неоднозначен, поэтому я не уверен, что вы также спрашиваете, нормально ли индексировать все внешние ключи. Однако, если вы, индексы должны быть созданы в столбцах, на которые часто ссылаются в запросах, и вы можете сделать следующее для повышения производительности:

  • Запустите мастер настройки базы данных, который предоставит сводку улучшений и рекомендует индексы.

  • Индексируйте все внешние ключи и запустите план выполнения (чтобы узнать, выполняются ли запросы быстрее или медленнее).

Чтобы создать индекс с помощью 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

Чтобы создать Script, который применяет индексы для всех внешних ключей, вы можете сделать это:

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

Ответ 2

Отличная работа, очень полезно.

Добавление расширения, которое включает в себя схему таблицы. Вы также можете исключить имена 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
      ''
)