Почему Sql Server Не Гарантирует Сортировку Результатов Без Order By

И снова здравствуйте.

OTUS снова запускает курс в июне «Разработчик MS SQL Server» , по традиции, накануне старта курса, мы начинаем делиться с вами материалом по теме.



Почему SQL Server не гарантирует сортировку результатов без ORDER BY

Если в вашем запросе нет ORDER BY, вы не можете быть уверены, что сортировка результатов не изменится со временем.

Конечно, поначалу все будет довольно предсказуемо, но по мере изменения (индексов, таблиц, конфигурации сервера, объема ваших данных) вы можете столкнуться с неприятными сюрпризами.

Начнем с простого: выполните SELECT для таблицы Users в базе данных Stack Overflow. Эта таблица имеет кластеризованный индекс в столбце Id, который начинается с единицы и увеличивается до триллиона.

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

Почему SQL Server не гарантирует сортировку результатов без ORDER BY

Но если вы создадите индекс по DisplayName и Location, то SQL Server внезапно решит использовать новый индекс, а не кластерный:

Почему SQL Server не гарантирует сортировку результатов без ORDER BY

Вот план выполнения:

Почему SQL Server не гарантирует сортировку результатов без ORDER BY

Почему SQL Server решил использовать этот индекс, хотя ему не нужно было сортировать по DisplayName и Location? Потому что этот индекс представляет собой наименьшую копию данных, которые необходимо получить.

Давайте посмотрим на размеры индексов с помощью

sp_BlitzIndex

:

Почему SQL Server не гарантирует сортировку результатов без ORDER BY

Кластеризованный индекс (CX/PK) имеет около 8,9 миллионов строк, а его размер 1,1 ГБ .

Некластеризованный индекс для DisplayName, Location также содержит около 8,9 миллионов строк, но его размер составляет всего лишь 368 МБ .

Если вам нужно выполнить сканирование, чтобы получить результаты запроса, то почему бы не выбрать самый маленький источник данных, так это будет быстрее.

Это причина, по которой SQL Server сделал это.



«Да, но мой запрос содержит ГДЕ».

Хорошо, теперь, когда у нас есть индекс для DisplayName и Location, давайте попробуем запрос, который ищет определенное имя (DisplayName).

Результаты сортируются по DisplayName:

Почему SQL Server не гарантирует сортировку результатов без ORDER BY

В плане выполнения вы можете видеть, что для DisplayName и Location используется индекс:

Почему SQL Server не гарантирует сортировку результатов без ORDER BY

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

Почему SQL Server не гарантирует сортировку результатов без ORDER BY

SQL Server обнаружил, что Алексов много, и имеет смысл выполнить сканирование кластерного индекса вместо поиска по индексу + поиск по ключу:

Почему SQL Server не гарантирует сортировку результатов без ORDER BY

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

В последнее время я столкнулся с гораздо более сложными случаями: Удаление индекса, который использовался в запросе Включите принудительную параметризацию, которая изменяет предполагаемое количество строк, заставляя SQL Server выбирать другой индекс.

Изменение уровня совместимости базы данных для включения нового средства оценки мощности, которое создает другой вариант плана.

Узнайте больше о курсе.

Теги: #sql #t-sql #индексирование

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.