Внешние ключи индексируются автоматически в SQL Server? - PullRequest
62 голосов
/ 10 ноября 2008

Может ли следующий оператор SQL автоматически создать индекс для Table1.Table1Column или он должен быть явно создан?

Ядром базы данных является SQL Server 2000

       CREATE TABLE [Table1] (
. . .
            CONSTRAINT [FK_Table1_Table2] FOREIGN KEY 
            (
                [Table1Column]
            ) REFERENCES [Table2] (
                [Table2ID]
            )

        )

Ответы [ 3 ]

60 голосов
/ 10 ноября 2008

SQL Server не будет автоматически создавать индекс для внешнего ключа. Также из MSDN:

Ограничение FOREIGN KEY не имеет быть связанным только с ПЕРВИЧНЫМ КЛЮЧОМ ограничение в другой таблице; оно может также будет определено для ссылки на столбцы УНИКАЛЬНОГО ограничения в другой стол. ИНОСТРАННЫЙ КЛЮЧ ограничение может содержать нулевые значения; однако, если какой-либо столбец составного Ограничение FOREIGN KEY содержит ноль значения, проверка всех значений которые составляют иностранный ключ ограничение пропущено. Чтобы убедиться что все значения составного иностранного КЛЮЧЕВОЕ ограничение проверено, укажите НЕ NULL на всех участвующих столбцы.

23 голосов
/ 10 ноября 2008

Когда я читаю вопрос Майка, он спрашивает, будет ли ограничение FK создавать индекс для столбца FK в таблице, в которой находится FK (таблица 1). Ответ - нет, и вообще. (для целей ограничения) этого делать не нужно. С другой стороны, столбец (столбцы), определенные как «TARGET» ограничения, должны быть уникальным индексом в ссылочной таблице, либо первичным ключом. или альтернативный ключ. (уникальный индекс) или создание правила создания ограничения не удастся.

(РЕДАКТИРОВАТЬ: Добавлено, чтобы явно иметь дело с комментарием ниже -) В частности, при обеспечении согласованности данных, для которой существует ограничение внешнего ключа. индекс может влиять на производительность ограничения DRI только для удалений строки или строк на стороне FK. При использовании ограничения во время вставки или обновления процессор знает значение FK и должен проверить наличие строки в ссылочной таблице на стороне ПК. Там уже есть индекс. При удалении строки на стороне PK он должен убедиться, что на стороне FK нет строк. Индекс может быть незначительно полезен в этом случае. Но это не обычный сценарий.

Кроме этого, в определенных типах запросов, однако, где обработчику запросов необходимо найти записи по многим сторонам объединения, которое использует этот столбец внешнего ключа. производительность соединения увеличивается на , если для этого внешнего ключа существует индекс. Но это условие свойственно использованию столбца FK в запросе соединения, а не наличию ограничения внешнего ключа ... Не имеет значения, является ли другая сторона соединения PK или каким-либо другим произвольным столбцом. Кроме того, если вам нужно отфильтровать или упорядочить результаты запроса на основе этого столбца FK, индекс поможет ... Опять же, это не имеет ничего общего с ограничением внешнего ключа для этого столбца.

6 голосов
/ 25 ноября 2015

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

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

В этом примере схема:

CREATE TABLE MasterOrder (
   MasterOrderID INT PRIMARY KEY)

CREATE TABLE OrderDetail(
   OrderDetailID INT,
   MasterOrderID INT  FOREIGN KEY REFERENCES MasterOrder(MasterOrderID)
)

OrderDetail будет сканироваться при каждом удалении записи в таблице MasterOrder. Вся таблица OrderDetail также будет сканироваться каждый раз, когда вы присоединяетесь к OrderMaster и OrderDetail.

   SELECT ..
   FROM 
      MasterOrder ord
      LEFT JOIN OrderDetail det
       ON det.MasterOrderID = ord.MasterOrderID
   WHERE ord.OrderMasterID = @OrderMasterID

Как правило, отсутствие индексации внешнего ключа является скорее исключением, чем правилом.

В случае отсутствия индексации внешнего ключа он никогда не будет использоваться. Это сделало бы ненужными дополнительные затраты на обслуживание сервера. Таблицы типов могут время от времени попадать в эту категорию, например:

CREATE TABLE CarType (
   CarTypeID INT PRIMARY KEY,
   CarTypeName VARCHAR(25)
)

INSERT CarType .. VALUES(1,'SEDAN')
INSERT CarType .. VALUES(2,'COUP')
INSERT CarType .. VALUES(3,'CONVERTABLE')

CREATE TABLE CarInventory (
   CarInventoryID INT,
   CarTypeID INT  FOREIGN KEY REFERENCES CarType(CarTypeID)
)

Исходя из общего предположения о том, что поле CarType.CarTypeID никогда не будет обновляться, а удаление записей будет почти никогда, серверные накладные расходы на поддержание индекса в CarInventory.CarTypeID не потребуются, если CarInventory никогда не ищется CarTypeID. 1024 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...