Предположим, у меня есть 2 таблицы, продукты и категории продуктов. Обе таблицы имеют отношение к CategoryId. И это запрос.
SELECT p.ProductId, p.Name, c.CategoryId, c.Name AS Category
FROM Products p
INNER JOIN ProductCategories c ON p.CategoryId = c.CategoryId
WHERE c.CategoryId = 1;
Когда я создаю план выполнения, таблица ProductCategories выполняет поиск по кластерному индексу, как и ожидалось. Но для табличных продуктов он выполняет сканирование индекса кластера, что вызывает у меня сомнения. Почему FK не помогает улучшить производительность запросов?
Поэтому я должен создать индекс для Products.CategoryId. Когда я снова создаю план выполнения, обе таблицы выполняют поиск по индексу. И оценочная стоимость поддерева значительно снижается.
Мои вопросы:
Помимо FK помогает в ограничении отношений, есть ли у него какая-либо другая полезность? Улучшает ли это производительность запросов?
Должен ли я создать индекс для всех столбцов FK (понравился Products.CategoryId) во всех таблицах?
источник
Иностранные ключи могут улучшить (и ухудшить) производительность
Как указано здесь: внешние ключи повышают производительность
Вы должны всегда создавать индексы для столбцов FK, чтобы уменьшить количество просмотров. SQL Server не делает это автоматически.
редактировать
Поскольку ссылка теперь кажется мертвой (благодарность Крису за то, что он заметил) , следующее показывает суть того, почему внешние ключи могут улучшить (и снизить) производительность.
Может ли внешний ключ улучшить производительность
источник
Внешний ключ - это концепция СУБД для обеспечения целостности базы данных.
Любые последствия / улучшения производительности будут зависеть от используемой технологии базы данных и будут вторичными по отношению к назначению внешнего ключа.
В SQL Server рекомендуется, чтобы на всех внешних ключах был хотя бы некластеризованный индекс.
Я надеюсь, что это прояснит ситуацию для вас, но вы можете запросить более подробную информацию.
источник
Ваша лучшая ставка на производительность - использовать индексы в тех областях, которые вы часто используете. Если вы используете SQL Server, вы можете использовать профилировщик для профилирования конкретной базы данных, взять файл, который выводится, и использовать мастер настройки, чтобы получить рекомендации о том, где разместить ваши индексы. Мне также нравится использовать профилировщик для очистки давно запущенных хранимых процедур, у меня есть список из десяти худших правонарушителей, который я публикую каждую неделю, чтобы люди были честными: D.
источник
Вы можете использовать его, чтобы сделать запрос более эффективным. Это позволяет вам реструктурировать запросы в SQL Server, чтобы использовать внешнее соединение вместо внутреннего, что устраняет необходимость проверки на серверах sql наличия нулевого значения в столбце. Вам не нужно вводить этот квалификатор, потому что отношение внешнего ключа уже сообщает вам об этом.
Итак, это:
Становится так:
Это не обязательно приведет к высокой производительности в небольших запросах, но когда таблицы станут большими, это может быть более эффективным.
источник
Для MySQL 5.7 это определенно может ускорить запросы, включающие множественные объединения!
Я использовал «объяснение», чтобы понять мой запрос, и обнаружил, что я объединяю 4-5 таблиц - где ключи вообще не использовались. Я ничего не сделал, кроме добавления внешнего ключа к этим таблицам, и в результате время загрузки сократилось на 90%. Запросы, которые заняли> 5 с, теперь занимают 500 мс или меньше.
Это ОГРОМНОЕ улучшение!
И, как уже упоминалось, вы получаете дополнительный бонус за обеспечение целостности отношений.
Помимо этого, обеспечение ссылочной целостности также имеет свои преимущества в производительности. Он имеет эффект второго порядка, гарантирующий, что таблицы, имеющие внешний ключ, «соответствуют» внешней таблице. Скажем, у вас есть таблица пользователей и таблица комментариев, и вы делаете некоторую статистику по таблице комментариев. Возможно, если вы трудно удалить пользователя, вы не хотите их комментарии больше, либо.
источник
Добавление внешнего ключа в таблицу не приведет к повышению производительности, просто говоря, что если вы вставляете запись в базу данных таблицы ProductCategories, то попытаетесь найти, что столбец внешнего ключа имеет значение, которое существует в значении первичного ключа таблицы продуктов, этот поиск, операция выполняется в вашей базе данных каждый раз, когда вы добавляете новую запись в таблицу ProductCategories. Таким образом, добавление внешнего ключа не улучшит производительность вашей базы данных, но позаботится о ее целостности. Да, это повысит производительность вашей базы данных, если вы проверяете целостность, используя внешний ключ, вместо того, чтобы выполнять много запросов для проверки наличия записи в базе данных в вашей программе.
источник
Я не очень разбираюсь в SQL-сервере, но в случае с Oracle наличие столбца внешнего ключа снижает производительность загрузки данных. Это потому, что база данных должна проверять целостность данных для каждой вставки. И да, как уже упоминалось, наличие индекса по столбцу внешнего ключа является хорошей практикой.
источник
Начиная с SQL Server 2008 внешние ключи могут влиять на производительность, влияя на то, как ядро базы данных выбирает оптимизацию запроса. Обратитесь к Star Join Heuristics в следующей статье: https://technet.microsoft.com/en-us/library/2008.04.dwperformance.aspx
источник