Повышает ли внешний ключ эффективность запросов?

Предположим, у меня есть 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 выполняет поиск индекса кластера, что является ожидаемым. Но для Table Products он выполняет сканирование индекса кластеров, что вызывает у меня сомнения. Почему FK не помогает повысить производительность запросов?

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

Мои вопросы:

  • Кроме того, FK помогает в ограничении связей, имеет ли он какую-либо другую полезность? Улучшает ли производительность запросов?

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

Ответ 1

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

Ответ 2

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

Edit

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

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

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

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

Ответ 3

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

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

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

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

Ответ 4

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

Ответ 5

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

Итак, это:

    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;

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

Ответ 6

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

Ответ 7

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

Ответ 8

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