И снова здравствуйте.
OTUS снова запускает курс в июне «Разработчик MS SQL Server» , по традиции, накануне старта курса, мы начинаем делиться с вами материалом по теме.
Если в вашем запросе нет ORDER BY, вы не можете быть уверены, что сортировка результатов не изменится со временем.
Конечно, поначалу все будет довольно предсказуемо, но по мере изменения (индексов, таблиц, конфигурации сервера, объема ваших данных) вы можете столкнуться с неприятными сюрпризами.
Начнем с простого: выполните SELECT для таблицы Users в базе данных Stack Overflow. Эта таблица имеет кластеризованный индекс в столбце Id, который начинается с единицы и увеличивается до триллиона.
Для этого запроса данные возвращаются в порядке кластеризованного индекса:
Но если вы создадите индекс по DisplayName и Location, то SQL Server внезапно решит использовать новый индекс, а не кластерный:
Вот план выполнения:
Почему SQL Server решил использовать этот индекс, хотя ему не нужно было сортировать по DisplayName и Location? Потому что этот индекс представляет собой наименьшую копию данных, которые необходимо получить.
Давайте посмотрим на размеры индексов с помощью sp_BlitzIndex
:
Кластеризованный индекс (CX/PK) имеет около 8,9 миллионов строк, а его размер 1,1 ГБ .
Некластеризованный индекс для DisplayName, Location также содержит около 8,9 миллионов строк, но его размер составляет всего лишь 368 МБ .
Если вам нужно выполнить сканирование, чтобы получить результаты запроса, то почему бы не выбрать самый маленький источник данных, так это будет быстрее.
Это причина, по которой SQL Server сделал это.
«Да, но мой запрос содержит ГДЕ».
Хорошо, теперь, когда у нас есть индекс для DisplayName и Location, давайте попробуем запрос, который ищет определенное имя (DisplayName).
Результаты сортируются по DisplayName:
В плане выполнения вы можете видеть, что для DisplayName и Location используется индекс:
Но если вы выполняете поиск по другому значению, результаты больше не будут сортироваться по DisplayName:
SQL Server обнаружил, что Алексов много, и имеет смысл выполнить сканирование кластерного индекса вместо поиска по индексу + поиск по ключу:
Даже в этих действительно простых случаях вы не можете гарантировать, что SQL Server всегда будет использовать ту копию данных, которую вы ожидаете.
В последнее время я столкнулся с гораздо более сложными случаями: Удаление индекса, который использовался в запросе Включите принудительную параметризацию, которая изменяет предполагаемое количество строк, заставляя SQL Server выбирать другой индекс.
Изменение уровня совместимости базы данных для включения нового средства оценки мощности, которое создает другой вариант плана.
Теги: #sql #t-sql #индексирование
-
Игры С Wi-Fi На Esp32
19 Oct, 24 -
Скромный Комплект Электронных Книг
19 Oct, 24