2009-02-03 3 views
118

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

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

Мои вопросы:

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

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

ответ

155

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

+9

+1: Модель - это одно. Производительность - другое. –

+27

Хорошие модели (как правило) работают лучше. –

+7

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

13

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

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

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

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

+4

Производительность проще, чем «целостность базы данных». –

+8

@ Kenny Evitt, если у вас нет целостности, ваши данные бесполезны. Я нахожу, что продает очень легко. – HLGEM

+0

@HLGEM Получение ошибки [404] (http://en.wikipedia.org/wiki/HTTP_404) время от времени все еще довольно терпимо. Имея исключительную пропускную способность взамен, используя более дешевые ресурсы и менее сложные системы, теперь это тоже очень легко продается. Вас может заинтересовать [C.A.P. теорема] (http://en.wikipedia.org/wiki/CAP_theorem). –

47

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

  1. Как указано здесь: Foreign keys boost performance

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

Редактировать

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

Can Foreign key improve performance

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

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

+2

Вот ссылка, в которой подробно описаны способы, с помощью которых они могут ухудшить производительность. http://www.devx.com/getHelpOn/10MinuteSolution/16595/0/page/2 – cmsjr

+2

Это имеет смысл, но вы столкнетесь только с этим delete. Возможно, заключение должно состоять в том, что в средах OLAP неиндексированные FK улучшат производительность, а в средах OLTP это ухудшит производительность. –

+1

Ссылка в этом ответе мертва. Это печально, так как это единственный аргумент для повышения производительности FK. –

3

Вы можете использовать его, чтобы помочь сделать запрос более эффективным. Это позволяет вам реструктурировать запросы в 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; 

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

+3

Не только внешние соединения обычно _less_ эффективны, чем внутренние соединения (http://stackoverflow.com/a/2726683/155892), теперь ваши запросы вводят в заблуждение: вы полагаетесь на базу данных, чтобы неявно включить ваши внешние соединения во внутренние соединения (восстановление производительности) вместо того, чтобы делать это явно –

4

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

1

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

1

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

Смежные вопросы