Создает ли внешний ключ индекс автоматически?

MS SQL Server 2000

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

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

10 ответов


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

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

поэтому имеет смысл индексировать любые столбцы, участвующие в FK, но a FK per se не является индексом.

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


Вау, ответы по всей карте. Так что документация говорит:

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

  • изменения ограничений первичного ключа проверяются с ограничениями внешнего ключа в связанных таблицах.

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

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


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


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

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

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

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


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


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


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


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


в PostgeSql вы можете проверить индексы самостоятельно, если вы нажмете \D tablename

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

Я думаю, что это отвечает на ваш вопрос, по крайней мере, для postgres.


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