Вопрос о том, как читать план выполнения SQL - PullRequest
6 голосов
/ 21 января 2010

Я выполнил запрос и включил фактический план выполнения. Есть один Hash Match, который мне интересен, потому что его поддерево использует сканирование индекса вместо поиска индекса. Когда я наводю курсор мыши на этот Hash Match, появляется раздел «Остаток зонда». Я предполагал, что это те ценности, к которым я присоединяюсь. Я прав здесь или есть лучшее объяснение, что это значит?

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

Ответы [ 4 ]

4 голосов
/ 21 января 2010

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

В вашем случае произошло следующее: QO заметил, что он может получить все значения столбца C из некластеризованного индекса, который содержит этот столбец (как ключ или как включенный столбец). Быть некластеризованным индексом, вероятно, довольно узко, поэтому общий объем операций ввода-вывода для сканирования всего некластеризованного индекса не является преувеличенным. QO также считает, что в системе достаточно оперативной памяти для хранения хеш-таблицы в памяти. При сравнении стоимости этого запроса (сканирование сквозного некластеризованного индекса, скажем, для 10000 страниц) со стоимостью вложенного цикла, который использовал поиск (скажем, 5000 тестов по 2-3 страницы каждый), сканирование выиграл как требующий меньше IO. Конечно, во многом это спекуляция с моей стороны, но я пытаюсь представить случай с точки зрения QO, и план, вероятно, является оптимальным.

Факторы, повлиявшие на выбор данного плана:

  • большое количество предполагаемых кандидатов на правой стороне объединения
  • доступность столбца соединения в узком некластеризованном индексе для левой стороны
  • много оперативной памяти

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

4 голосов
/ 21 января 2010

Этот пост в блоге, вероятно, ответит на ваш первый вопрос.

Что касается второго, то сканирование индекса может быть выбрано оптимизатором в ряде ситуаций. С макушки головы:

  • Если индекс очень маленький
  • Если большая часть строк в индексе будет выбрана по запросу

  • Если вы используете функции в предложении where вашего запроса

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

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

Ознакомьтесь с отличными статьями о планах выполнения на simple-talk.com:

.

У них также есть бесплатная электронная книга Планы выполнения SQL Server для загрузки.

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

1 / Hash Match означает, что он принимает хеш столбцов, используемых в соединении равенства, но должен включать все другие столбцы, участвующие в соединении (для> и т. Д.), Чтобы их тоже можно было проверить. Вот где вступают остаточные столбцы.

2 / Поиск индекса можно выполнить, если он идет прямо к нужным строкам. Возможно, вы применяете вычисления к столбцам и используете это? Затем он будет использовать индекс в качестве уменьшенной версии данных, но все равно должен будет проверять каждую строку (применяя расчет к каждой).

...