2011-01-20 3 views
3
.

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

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

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% от общей стоимости запроса. Его план выполнения такой же, как и остальные, за исключением того, что шаг Key Lookup имеет стоимость 100% по сравнению с Index Seek. В двух других запросах он ближе к 50%.

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

ответ

1

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

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

Оптимизатор запросов (QO) работает, просматривая статистику по индексам.Индекс на поле b может иметь среднюю мощность 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 будет показывать разные оценочные строки для каждого? Тем не менее, если вы запустили запросы, если не задействовано параметризация/планирование-кэширование, вероятно, 2-й будет использовать clustered index для сканирования таблицы вместо того, чтобы выполнять 80% -ный (дорогой) поиск по закладкам.

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

set statistics io on 
set statistics time on 
0

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

Лучше посмотреть фактические планы выполнения в сочетании с статистикой io и времени, чтобы понять, что на самом деле происходит.

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'; 

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

2

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

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