Нужно ли создавать индексы для внешних ключей? - PullRequest
108 голосов
/ 08 ноября 2010

У меня есть таблица A и таблица B. A имеет внешний ключ для B первичного ключа B, B_ID.

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

Нужно ли отдельно создавать индекс для A.B_ID или это должно обеспечить наличие внешнего ключа?

Ответы [ 6 ]

123 голосов
/ 08 ноября 2010

Только ограничение внешнего ключа не обеспечивает индекс - нужно (и нужно) создать.

41 голосов
/ 08 ноября 2010

Создание внешнего ключа не приводит к автоматическому созданию индекса для A.B_ID. Поэтому с точки зрения производительности запросов обычно имеет смысл создать отдельный индекс для A.B_ID.

Если вы когда-либо удаляете строки в B, вы определенно хотите, чтобы A.B_ID был проиндексирован. В противном случае Oracle придется выполнять полное сканирование таблицы на A каждый раз, когда вы удаляете строку из B, чтобы убедиться, что нет потерянных записей (в зависимости от версии Oracle, могут быть и дополнительные последствия блокировки, но они уменьшаются в более поздних версиях Oracle).

23 голосов
/ 09 ноября 2010

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

Большинство времени, однако, вы захотите создать индекс (на самом деле, в Oracle Apex есть отчет о «неиндексированных внешних ключах»).

Всякий раз, когда приложение должно иметь возможность удалить строку в родительской таблице или обновить значение PK (что является более редким), DML пострадает, если индекс не существует, потому что ему придется заблокировать всю дочернюю таблицу.

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

12 голосов
/ 08 ноября 2010

SQL Server никогда не помещал индексы в столбцы внешнего ключа автоматически - посмотрите превосходное сообщение в блоге Кима Триппа об истории и истории этого городского мифа.

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

6 голосов
/ 05 ноября 2014

По соображениям производительности должен быть создан индекс.Используется в операциях удаления первичной таблицы (чтобы убедиться, что удаляемая запись не используется) и в соединениях, в которых обычно используется внешний ключ.Может быть только несколько таблиц (я не создаю их в журналах), которые не нуждаются в индексе, но, вероятно, в этом случае, вероятно, вам также не нужно ограничение внешнего ключа.1004 * Есть некоторые базы данных, которые уже автоматически создают индексы для внешних ключей.Jet Engine (файлы Microsoft Access) Firebird MySQL

НАДЕЖНО

SQL Server Oracle

НЕ

1 голос
/ 09 ноября 2010

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

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

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