Индексируются ли внешние ключи автоматически в SQL Server?

StackOverflow https://stackoverflow.com/questions/278982

Вопрос

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

Ядро базы данных — SQL Server 2000.

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

        )
Это было полезно?

Решение

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

  

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

Другие советы

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

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

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

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

  • Каждый раз запись удаляется из ссылочной (родительской) таблицы.
  • Каждый раз две таблицы соединяются по внешнему ключу.
  • Каждый раз столбец 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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top