несовместимый поиск ключей в плане выполнения SQL Server - PullRequest
3 голосов
/ 21 января 2011

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

В таблице довольно много столбцов, и я добавил некластеризованные индексы для трех разных столбцов.

SELECT * FROM table WHERE Field1 = 10;
SELECT * FROM table WHERE Field2 = 40;
SELECT * FROM table WHERE Field3 = 'A';

Field1 и Field2 - это целочисленные поля, а Field3 - это varchar.

Когда я запрашиваю примерный план выполнения запроса у SQL Server для этих трех запросов, я получаю в основном один и тот же план для каждого:

SELECT -> Nested Loop -> Index Seek
                      -> Key Lookup

Но я считаю, что это время исполнения крайне несовместимо. В частности, второй запрос занимает 98% от общей стоимости запроса. Его план выполнения такой же, как и у других, за исключением того, что шаг поиска ключа стоит 100% по сравнению с поиском по индексу. В двух других запросах он ближе к 50%.

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

Ответы [ 3 ]

2 голосов
/ 21 января 2011

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

Что касается индексации вашей таблицы, если вы можете включить в свой индекс как можно больше столбцов критериев,тогда тебе может быть лучше.В зависимости от ваших данных, вы можете получить больший прирост путем индексации по наиболее избирательному столбцу (столбцу, который, скорее всего, будет удалять большинство данных), во-первых.(Однако это не обязательно так, особенно если вы объединяетесь с другими таблицами, сортируете результаты и т. Д.) Вы можете добавлять другие столбцы по мере необходимости или выгоды.Вы можете использовать предложение «include» при создании индекса, чтобы добавить менее селективные столбцы «where» в индекс, чтобы уменьшить количество требуемых поисков ключей.

1 голос
/ 21 января 2011

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

Все зависит от текущей статистики ожидаемых длин ключей.

Оптимизатор запросов (QO) работает, просматривая статистику по индексам. Индекс по fieldb может иметь среднюю мощность множества 100, тогда как индекс по другим полям - среднюю мощность 10000 (в 100 раз более конкретно). Так что это дает вам относительную индикацию, основанную на averaged плане.

Чтобы увидеть особенности, всегда включайте статистику *, но на самом деле это дает только actual execution time определенных значений. В некоторых отношениях QO может быть более точным в долгосрочной перспективе, если переменные доступа являются случайными.

Рассмотрим случай этих двух запросов

SELECT * FROM table WHERE Field2 = 40;
SELECT * FROM table WHERE Field2 = 42;

Скажем, гипотетически 42 - это специальный код, который используется в 80% всех записей. 40 - это уникальный код, используемый только в 1 записи. Вы не можете ожидать, что QO покажет разные оценочные строки для каждого? Тем не менее, если вы выполняли запросы, если не задействовано параметризация / кэширование плана, вполне вероятно, что второй будет использовать clustered index для сканирования таблицы вместо выполнения 80% (дорогого) поиска закладок.

* для включения статистической отчетности

set statistics io on
set statistics time on
0 голосов
/ 21 января 2011

Я видел несколько случаев, когда процентная доля «стоимости запроса (относительно партии)» может быть, по меньшей мере, вводящей в заблуждение, если не сказать больше.статистика, чтобы понять, что на самом деле происходит.

set statistics io on
set statistics time on

SELECT * FROM table WHERE Field1 = 10;
SELECT * FROM table WHERE Field2 = 40;
SELECT * FROM table WHERE Field3 = 'A';

Затем посмотрите на логическое чтение, время ЦП и истекшее время, возвращенное для каждого запроса.

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