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


MS SQL Server 2000

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

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

10 327

10 ответов:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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