Skip to content

Любопытный случай сортировки с Top N

Пересказ статьи DANIEL HUTMACHER. The curious case of the Top N Sort


Просматривая сессию саммита PASS 2017 Брента Озара на Youtube, я узнал, что оператор сортировки Top N в SQL Server резко меняет свое поведение в зависимости от того, сколько строк вы хотите получить из TOP.

Рассмотрим следующий пример запроса в базе данных Stack Overflow:
SELECT TOP (250) Id, DisplayName, DownVotes
FROM dbo.Users
ORDER BY DownVotes DESC;

SQL Server будет сканировать все строки из таблицы Users (поскольку не существует индекса на столбце DownVotes), затем отсортирует эти строки, чтобы получить только 250 самых несчастных пользователей с наибольшим числом голосов против.



Сортировка всех этих строк довольно дорогая, поскольку это большая таблица:


Выделение 328Мб памяти для 250 строк

Но в SQL Server имеется встроенная (недокументированная) быстрая оптимизация. Если вы возвращаете не более 100 строк, внутреннее поведение оператора Top N Sort меняется.

SELECT TOP (100) Id, DisplayName, DownVotes
FROM dbo.Users
ORDER BY DownVotes DESC;

Посмотрите, что происходит с выделением памяти:


Получите 100 строк по цене всего 1 МБ памяти!

Причиной, что такое незначительное изменение запроса требует настолько меньше памяти, является то, фактически сохраняется и сортируется не весь набор данных из оператора Clustered Index Scan, как это бы делал обычный Sort.

Поскольку данных относительно немного, я предполагаю, что SQL Server просто держит первых 100 строк во внутренней рабочей таблице в памяти. Для каждой новой строки, возвращаемой оператором Scan, Top N Sort проверяет, относится ли эта строка к первым 100. Если так, эта строка вставляется в рабочий набор, а текущая последняя строка (101-я), вытесняется из рабочего набора. И так далее.

В любой точке итерационного процесса нам необходимо ровно столько памяти, сколько необходимо для хранения этой рабочей таблицы.

Не только память


Это отражается не только на распределении памяти, но также на времени выполнения. Запрос с TOP(101) потребует почти вдвое больше времени по сравнению с аналогичным запросом с TOP(100).

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

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

Комментарии

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

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

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

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

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

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