Внешний ключ автоматически создает индекс? - PullRequest
345 голосов
/ 07 мая 2009

Мне сказали, что если я получу внешний ключ от двух таблиц, SQL Server создаст что-то похожее на индекс в дочерней таблице. Мне трудно поверить, что это правда, но я не могу найти многое, связанное именно с этим.

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

Ответы [ 10 ]

305 голосов
/ 07 мая 2009

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

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

Так что имеет смысл индексировать любые столбцы, включенные в FK, но FK как таковой не является индексом.

Ознакомьтесь с превосходной статьей Кимберли Триппа "Когда SQL Server прекратил помещать индексы в столбцы внешнего ключа?" .

39 голосов
/ 07 мая 2009

Ух ты, ответы есть по всей карте. Так что Документация гласит:

Ограничение FOREIGN KEY является кандидатом на индекс, потому что:

  • Изменения ограничений PRIMARY KEY проверяются с помощью ограничений FOREIGN KEY в связанных таблицах.

  • Столбцы внешнего ключа часто используются в критериях объединения, когда данные из связанных таблиц объединяются в запросах путем сопоставления столбцов в ограничении FOREIGN KEY одной таблицы со столбцами первичного или уникального ключа. в другой таблице. Индекс позволяет Microsoft® SQL Server ™ 2000 быстро находить связанные данные в таблице внешнего ключа. Однако создание этого индекса не является обязательным требованием. Данные из двух связанных таблиц могут быть объединены, даже если между таблицами не определены ограничения PRIMARY KEY или FOREIGN KEY, но отношение внешнего ключа между двумя таблицами указывает, что эти две таблицы были оптимизированы для объединения в запросе, который использует ключи как его критерии.

Так что кажется довольно ясным (хотя документация немного запутана), что на самом деле он не создает индекс.

18 голосов
/ 07 мая 2009

Нет, неявный индекс для полей внешнего ключа отсутствует, иначе почему бы Microsoft сказала «Создание индекса по внешнему ключу часто полезно» . Ваш коллега может перепутать поле внешнего ключа в ссылающейся таблице с первичным ключом в указанной таблице - первичные ключи do создают неявный индекс.

6 голосов
/ 07 мая 2009

Скажем, у вас есть большой стол, называемый заказами, и маленький стол, называемый клиентами. Существует внешний ключ от заказа к клиенту. Теперь, если вы удаляете клиента, Sql Server должен проверить, что нет орфанных заказов; если они есть, возникает ошибка.

Чтобы проверить, есть ли какие-либо заказы, Sql Server должен выполнить поиск в таблице больших заказов. Теперь, если есть индекс, поиск будет быстрым; если нет, поиск будет медленным.

Так что в этом случае медленное удаление может быть объяснено отсутствием индекса. Особенно, если Sql Server придется искать 15 больших таблиц без индекса.

P.S. Если внешний ключ имеет значение ON DELETE CASCADE, Sql Server все равно должен выполнить поиск в таблице заказов, но затем удалить все заказы, которые ссылаются на удаленного клиента.

6 голосов
/ 07 мая 2009

SQL Server автоматически создает индексы для первичных ключей, но не для внешних ключей. Создайте индекс для внешних ключей. Это, вероятно, стоит накладных расходов.

4 голосов
/ 16 апреля 2014

Внешние ключи не создают индексы. Только ограничения альтернативного ключа (UNIQUE) и ограничения первичного ключа создают индексы. Это верно для Oracle и SQL Server.

3 голосов
/ 07 мая 2009

Строго говоря, внешние ключи не имеют абсолютно никакого отношения к индексам, да. Но, как указали вышеупомянутые ораторы, имеет смысл создать такой, чтобы ускорить поиск в FK. Фактически, в MySQL, если вы не укажете индекс в объявлении FK, механизм (InnoDB) создаст его для вас автоматически.

3 голосов
/ 07 мая 2009

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

2 голосов
/ 02 сентября 2015

Я заметил, что Entity Framework 6.1, на который указывает MSSQL, автоматически добавляет индексы для внешних ключей.

2 голосов
/ 07 июля 2012

В PostgeSql вы можете самостоятельно проверить наличие индексов, если нажмете \ d имя_таблицы

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

Думаю, это ответит на ваш вопрос хотя бы для postgres.

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