Skip to content

TOP или Max/Min: есть ли разница?

Пересказ статьи Mike Byrd. TOP vs Max/Min: Is there a difference


Я всегда стараюсь больше узнать работе черного ящика оптимизатора, и недавно заинтересовался тем, как он решает следующие запросы:

Таблица dbo.Entity содержит 31404767 строк. Все 4 запроса имеют одинаковые показатели ввода/вывода: число сканирований 1, логических чтений 4, физических чтений 0 и т.д., а планы этих запросов выглядят так:



Хм, интересно! Я думал, что оптимизатор мог прийти к одному и тому же плану выполнения для каждого запроса, однако запросы с TOP приводят к несколько более сложному плану. Давайте оценим 4 плана и посмотрим на отличия.

Похоже, что все 4 одинаковы по стоимости запроса (относительно пакета): 25%, но если посмотреть на фактические числа, то запросы 1 и 2 имеют стоимость поддерева



Это небольшая разница (0.0000043), но все же разница. Если внимательно посмотреть на различие в двух планах, то в запросах 1 и 2 мы имеем оператор Stream Aggregate, а в запросах 3 и 4 - дополнительные операторы Compute Scalar, Constant Scan и Nested Loop.



Я не собираюсь обсуждать относительные метрики этих операторов, а лишь один факт, не показанный здесь, который заключается в том, что все 4 запроса имеют время ЦП 0 секунд (на самом деле это менее 0,5 миллисекунды), но затраченное время для всех 4 запросов, неизменно показывало увеличение времени в 4-8 для запросов 3 и 4 по сравнению с запросами 1 и 2.

Запросы 1 и 3 завершаются сканированием вперед кластеризованного индекса (MIN), а запросы 2 и 4 - сканированием назад кластеризованного индекса (MAX), и каждый возвращает единственную строку, как показано на схеме ниже:



Именно этот результат (и ответ) я ожидал получить на всех 4 запросах, но действительно интересно, откуда все остальные операторы в плане запроса, ь.к. я полагал, что оптимизатор достаточно "умен" для того, чтобы распознать простые запросы и не требовать лишних операторов. :-)

Наконец, я изначально совсем не ожидал увидеть здесь 4 логических чтения. После выполнения следующего запроса

dbcc showcontig ('dbo.Entity') 
with tableresults, all_indexes, all_levels;


частичные результаты имеют вид



При 4 уровнях в B-Tree, несмотря на то, что возвращается только одна строка, запросам необходимо пройти 4 уровня (т.е. прочитать 4 страницы) для получения данных одной строки.

Итак, что мы узнали? Кажется, что агрегатные функции MAX, MIN и функция TOP все начинают со сканирования одного и того же индекса, однако то, как затем оптимизатор использует промежуточные результаты, слегка отличается. Есть ли большой выигрыш в использовании TOP? Я бы не сказал, но если бы эти операторы T-SQL вызывались тысячи раз в течение короткого периода времени, возможно, вы бы рассмотрели вариант использования MAX и MIN вместо функции TOP.

Обратные ссылки

Нет обратных ссылок

Комментарии

Показывать комментарии Как список | Древовидной структурой

Нет комментариев.

Автор не разрешил комментировать эту запись

Добавить комментарий

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA

Form options

Добавленные комментарии должны будут пройти модерацию прежде, чем будут показаны.