Как думать подобно 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 тысяч долларов за ядро.
Обратные ссылки
Автор не разрешил комментировать эту запись
Комментарии
Показывать комментарии Как список | Древовидной структурой