Что я должен сделать, чтобы получить поиск кластеризованного индекса вместо сканирования кластерного индекса?

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

Я буду признателен за любую помощь с этим.

Спасибо,

Брайан

2 ответа

Решение

Без какой-либо детали трудно угадать, в чем проблема, и даже является ли она проблемой вообще. Выбор сканирования вместо поиска может быть обусловлен многими факторами:

  • Запрос выражает набор результатов, который охватывает всю таблицу. То есть. запрос прост SELECT * FROM <table>, Это тривиальный случай, который будет полностью охвачен сканированием индекса с привязкой без необходимости рассматривать что-либо еще.
  • У оптимизатора нет альтернатив:
    • запрос выражает подмножество всей таблицы, но предикат фильтрации находится в столбцах, которые не являются частью кластеризованного ключа, и в этих столбцах также отсутствуют некластированные индексы. Это не альтернативный план, кроме полного сканирования.
    • У запроса есть предикаты фильтрации для столбцов в замкнутом ключе индекса, но они не являются аргументами SARGable. Фильтрующий предикат обычно необходимо переписать, чтобы сделать его SARGable, правильная перезапись зависит от случая к случаю. Более тонкая проблема может появиться из-за неявных правил преобразования, например. предикат фильтрации WHERE column = @value но столбец VARCHAR (Ascii) и @value NVARCHAR (Unicode).
    • Запрос имеет предикаты фильтрации SARGale для столбцов в кластеризованном ключе, но крайний левый столбец не фильтруется. То есть. привязанный индекс по столбцам (foo, bar) но предложение WHERE включено bar в одиночестве.
  • Оптимизатор выбирает сканирование.
    • Если альтернативой является некластеризованный индекс, то выполняется сканирование (или поиск диапазона), но выбор заключается в том, чтобы использовать кластеризованный индекс, причину обычно можно отследить до критической точки индекса из-за отсутствия покрытия некластеризованного индекса для запроса. проекция. Обратите внимание, что это не ваш вопрос, так как вы ожидаете, что поиск по кластерному индексу, а не поиск по некластерному индексу (предполагается, что вопрос на 100% точен и задокументирован...)
    • Оценки кардинальности. Оценка стоимости запроса основана на статистических данных ключа (-ов) кластерного индекса, которые обеспечивают оценку количества результатов (т. Е. Сколько строк будет соответствовать). По простому запросу это не может произойти, так как любая оценка для поиска или поиска по диапазону будет ниже, чем оценка для сканирования, независимо от статистики, но для сложного запроса, с объединениями и фильтрами для нескольких таблиц, вещей являются более сложными, и план может включать в себя сканирование, где ожидался поиск, потому что оптимизатор запросов может выбрать план, для которого порядок оценки объединения обратен тому, что ожидает наблюдатель. Обратный порядок выбора может быть правильным (чаще всего) или может быть проблематичным (обычно из-за устаревания статистики или перехвата параметров).
    • Гарантия заказа. Сканирование даст результаты в гарантированном порядке, и элементы, расположенные выше в дереве выполнения, могут извлечь выгоду из этого порядка (например, сортировка или спул могут быть исключены, или вместо хеш / вложенных объединений может использоваться объединение слиянием). В целом стоимость запроса лучше в результате выбора явно более медленного пути доступа.

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

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

Так, если в индексе b-дерева, скажем, 5 уровней, то если запрос сгенерирует более 20% строк в таблице, дешевле прочитать всю таблицу, чем сделать 5 операций ввода-вывода для каждого из 20%. строки...

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

Другие вопросы по тегам