Skip to content

Как думать подобно SQL server: добавление предложения ORDER BY

Пересказ статьи Brent Ozar. How to Think Like the SQL Server Engine: Adding an ORDER BY


Серию статей "Как думать..." начинаем простым запросом с предложением WHERE:



А теперь давайте добавим ORDER BY:

SELECT Id 
FROM dbo.Users
WHERE LastAccessDate > '2014/07/01'
ORDER BY LastAccessDate;

Вот измененный план - заметьте, что стоимость запроса утроилась до 17.72. Давайте выясним почему:



Мы читаем план справа налево, проводя мышью над каждым оператором. Каждый оператор представляет как бы самостоятельную программу, которая должна сделать назначенную работу и произвести конкретный вывод.

Первое, что происходит, это сканирование кластеризованного индекса.


Вверху справа сканирование кластеризованного индекса в точности то же, что и в последнем запросе. Наведите мышку на этот оператор, и появится много сочных деталей, которые мы до сих пор не рассматривали:



  • Predicate (предикат): минипрограмма сканирования кластеризованного индекса собирается вернуть только те строки, для которых LastAccessDate > '2014-07-01'. (Довольно изящно она изменила формат даты и добавила время, не так ли?)

  • Estimated Number of Rows (оценка числа строк): 149259.

  • Estimated Number of Rows to be Read (предположительное число строк, которые необходимо прочитать): 299398 (мы должны просканировать всю таблицу, чтобы найти людей, отвечающих критерию).

  • Output List (список столбцов вывода): Id, LastAccessDate (поскольку следующей в направлении потока данных минипрограмме требуются как Id, так и LastAccessDate. Конкретно, это оператор сортировки (Sort), который должен выполнить сортировку всех этих строк по LastAccessDate.)


Данные вытекают из этого оператора сканирования и втекают в следующий оператор: Sort.

Следующее действие - сортировка.


На входе сортировки 148328 строк Id и LastAccessDate, которые выходят из сканирования кластеризованного индекса, и которые не имеют какого-либо порядка - но наш запрос просит отсортировать их по LastAccessDate. Здесь и начинается работа сортировки. Наведите курсор мышки на оператор, чтобы увидеть то, что происходит в этой минипрограмме:



Интересные пункты:

  • Order By (внизу): главная цель сортировки.

  • Оценка числа строк: 149259.

  • Estimated I/O Cost (оценка стоимости ввода/вывода): 0.01 (поскольку ввод/вывод небольшой, если сортируется 150К строк).

  • Estimated CPU Cost (оценка стоимости затрат процессора): 11.7752 (поскольку сортировка - это в основном работа процессора).


Но заметим, что все эти оценки базируются на 149259 строках. Если придет больше (или меньше) строк, то фактическая работа была бы больше (или меньше). Самое время остановиться и сказать, что вы не видите здесь цифр фактической стоимости: SQL Server не возвращается назад и не пересчитывает значения после выполнения работы. Всякий раз, когда вы видите стоимость - даже на фактическом плане - это только оценка, полученная прежде, чем запрос начнет выполняться. Как и вы, SQL Server задним числом не признает, насколько был превышен бюджет или просрочена работа.

Итак, почему стоимость запроса утроилась с 6 до 18?


Дело сводится к стоимости 11.7752 оператора сортировки, который появился в нашем плане. Сортировка данных - это тяжелая работа.

Я шучу, что SQL Server является вторым самым дорогим местом в мире для сортировки данных - уступая только Oracle. Когда кто-то будет жаловаться на стоимость ядра SQL Server Enterprise Edition в 7 тысяч долларов, напомните им, что Oracle стоит 47 тысяч долларов за ядро.

Если вам необходимо отсортировать данные, попробуйте это сделать в слое приложения. Разработчики действительно хорошо разбираются в масштабировании приложений, и их серверы приложений не стоят 7 тысяч долларов за ядро. Если запрос не использует TOP, то ему, вероятно, не требуется и ORDER BY.

Что вы говорите? Вы никогда не слышали о таком совете распределения нагрузки от Майкрософт?

Microsoft, компания, которая взимает $7K за ядро, чтобы сделать за вас сортировку? Они не сказали вам об этом? Да. Должно быть, вы слишком заняты мыслями об использовании R, Python и Java внутри SQL Server, и все это по низкой цене - 7 тысяч долларов за ядро.

Trackbacks

No Trackbacks

Comments

Display comments as Linear | Threaded

No comments

The author does not allow comments to this entry

Add Comment

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

Submitted comments will be subject to moderation before being displayed.