Могут ли внешние ключи снизить производительность запросов? - PullRequest
18 голосов
/ 17 ноября 2009

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

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


1) Термин запрос вводит в заблуждение. Меня интересуют все виды штрафов за исполнение.

2) Есть ли у кого-нибудь реальные цифры о негативном влиянии на операторы INSERT, DELETE или UPDATE (я знаю, что это зависит от конкретной системы, но, тем не менее, любые измерения в реальном мире приветствуются)?

Ответы [ 11 ]

21 голосов
/ 17 ноября 2009

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

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

16 голосов
/ 17 ноября 2009

Я предполагаю, что для запросов INSERT ограничения, в том числе ограничения внешнего ключа, несколько снизят производительность. База данных должна проверить, что все, что вы сказали ей вставить, является тем, что ваши ограничения позволяют вставлять.

Для запросов SELECT ограничения внешнего ключа не должны вносить никаких изменений в производительность.

Поскольку ВСТАВКИ почти всегда очень быстрые, небольшое количество дополнительного времени не будет заметно, за исключением крайних случаев. (При создании базы данных объемом в несколько гигабайт вы можете отключить ограничения, а затем включить их позже, если вы уверены, что данные в порядке.)

5 голосов
/ 17 ноября 2009

Теоретически, да: записи данных должны проверять ограничения.

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

  • неверный дизайн схемы (отсутствующие индексы, неправильный выбор кластеризованного индекса)
  • конфликт (блокировка), опять-таки из-за неправильной схемы (сканирование таблиц гарантирует конфликты блокировок)
  • плохой дизайн запроса

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

Мой 2c: Никогда пожертвуйте ограничениями на правильность ради некоторых неуловимых целей производительности. В очень редком случае, когда ограничения действительно являются проблемой, есть измерения, чтобы показать, что это так, и, как говорится: если вам нужно спросить, сколько это стоит, вы не можете себе это позволить. Если вам нужно спросить, могут ли ограничения быть проблемой, вы не можете их удалить (без обид).

4 голосов
/ 17 ноября 2009

Для INSERT / UPDATE / DELETE краткий ответ «Да». База данных должна будет проверить, что ссылочная целостность не повреждена и что создание / изменение разрешено. Или в случае DELETE может быть сделано каскадирование.

Для SELECTs это на самом деле совсем наоборот. Иностранные ключи имеют дополнительное секретное преимущество: они показывают, где именно вы, скорее всего, будете выполнять сложные JOIN-ы, и у которых очень часто используются поля. Это значительно упрощает работу по индексированию, и вы можете в значительной степени гарантировать, что все ваши поля FK должны быть проиндексированы. Это делает SELECTs намного быстрее.

4 голосов
/ 17 ноября 2009

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

Вам нужно будет проиндексировать их, чтобы повысить производительность при выборе запросов.

3 голосов
/ 08 февраля 2013

Проверка внешнего ключа занимает больше времени, чем думает большинство людей. Текущий тест с Oracle 11g и таблицей с двумя внешними ключами показал, что время вставки около 800 000 строк заняло 60 секунд с включенными внешними ключами, но только 20 секунд без внешних ключей. (Столбцы внешнего ключа были проиндексированы, конечно)

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

2 голосов
/ 17 ноября 2009

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

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

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

2 голосов
/ 17 ноября 2009

Если бы внешние ключи оказывали какое-либо влияние таким образом, это было бы для INSERTS. База данных выполняет ссылочную проверку внешних ключей, когда записи создаются / изменяются, а не выбираются.

0 голосов
/ 22 июня 2015

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

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

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

Конечно, все это предполагает, что используется проверка внешнего ключа.

0 голосов
/ 17 ноября 2009

Если вы применяете ссылочную целостность, INSERT и UPDATE, которые влияют на поле FK, будут работать медленнее. Тем не менее, обычно беспокоиться не о чем, тем более что многие БД читают на 80% / пишут на 20%. Это также цена, которую стоит заплатить.

Создание индекса по внешнему ключу часто выгодно, хотя, очевидно, это зависит от того, какие операторы SELECT вы используете.

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

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