Улучшает ли внешний ключ производительность запросов?



Предположим, у меня есть 2 таблицы, продукты и ProductCategories. Обе таблицы имеют отношение к 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 не помогает повысить производительность запросов?



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



мои вопросы:




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


  2. должен ли я создать индекс для всех столбцов FK (понравившиеся продукты.CategoryId) во всех таблицах?


1196   9  

9 ответов:

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

внешние ключи могут улучшить (и повредить) производительность

  1. Как указано здесь: внешние ключи повышают производительность

  2. вы всегда должны создавать индексы для столбцов FK, чтобы уменьшить поиск. SQL Server не делает это автоматически.

Edit

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

может ли внешний ключ повысить производительность

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

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

внешний ключ-это концепция СУБД для обеспечения целостности базы данных.

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

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

Я надеюсь, что это проясняет для вас, но, пожалуйста, не стесняйтесь просить более детально.

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

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

значит так:

    select p.ProductId, p.Name, c.CategoryId, c.Name AS Category 
from Products p inner join ProductCategories c on p.CategoryId = c.CategoryIdwhere c.CategoryId = 1;

становится этот:

SELECT p.ProductId, p.Name, c.CategoryId, c.Name AS Category 
FROM ProductCategories c 
LEFT OUTER JOIN Products P ON
c.CategoryId = p.CategoryId 
WHERE c.CategoryId = 1;

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

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

добавление внешнего ключа в таблицу не улучшит производительность, просто говоря, что если вы вставляете запись в базу данных таблицы ProductCategories, вы попытаетесь найти столбец внешнего ключа, который существует в значении первичного ключа таблицы products, этот поиск, операция накладные расходы на вашу базу данных каждый раз, когда вы добавляете новую запись в таблицу ProductCategories. Таким образом, добавление внешнего ключа не улучшит производительность вашей базы данных, но позаботится о целостности вашего база данных. Да, это улучшит производительность вашей БД, если вы проверяете целостность с помощью внешнего ключа вместо выполнения многих запросов для проверки записи существует в базе данных в вашей программе.

для MySQL 5.7, это определенно может ускорить запросы, связанные с несколькими соединениями удивительно хорошо!

Я использовал "объяснить", чтобы понять мой запрос и обнаружил, что я присоединялся к 4-5 таблицам - где вообще не использовались ключи. Я ничего не сделал, но добавил внешний ключ к этим таблицам, и результатом стало сокращение времени загрузки на 90%. Запросы, которые заняли >5s, теперь занимают 500 мс или меньше.

Это огромное улучшение!

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

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

начиная с SQL Server 2008 внешние ключи могут влиять на производительность, влияя на то, как компонент database engine выбирает оптимизацию запроса. См. эвристику соединения звезд в следующей статье:https://technet.microsoft.com/en-us/library/2008.04.dwperformance.aspx

Comments

    Ничего не найдено.