Кластерный индекс в Client
поле таблицы LastName
.
Когда я просто выкидываю все записи из таблицы, они отображаются в алфавитном порядке, если только (nolock)
подсказка не используется в рассматриваемом запросе. Этот намек меняет порядок записей. Должно ли это? Я уверен, что ни у одной другой сессии нет открытой транзакции с изменениями в этой таблице (по крайней мере sp_who2
, не показывает мне ничего).
Как объяснить разницу в заказе?
Дополнительная информация, извлеченная из комментариев:
Там нет заказа по. Должен ли некластерный индекс обеспечивать порядок?
Запросы по-прежнему возвращают другой порядок, даже если используется указатель индекса, указывающий кластеризованный индекс. Должны ли они? Мне интересно, почему
nolock
меняется порядок возвращаемых записей без видимого изменения планов.Я сделал WinDiff для них - то же самое за исключением [the]
(nolock)
[подсказка запроса].
Ответы:
Появление упорядоченного результирующего набора без
ORDER BY
предложения часто является результатом сканирования, извлекающего строки в порядке индекса. Одна из причин, по которой сканирование в порядке индекса обычно выбирается в соответствии сREAD COMMITTED
уровнем изоляции по умолчанию, заключается в том, что оно уменьшает вероятность нежелательных аномалий параллелизма, таких как многократное обнаружение одной и той же строки или полный пропуск некоторых строк. Это подробно описано в нескольких местах, в том числе в этой серии статей об уровнях изоляции.С
NOLOCK
табличной подсказкой это поведение смягчается, и доступ к таблице осуществляется при более терпимомREAD UNCOMMITTED
уровне изоляции, который может сканировать данные в порядке размещения вместо порядка индекса. Как описано в этой ссылке, решение о том, использовать ли сканирование порядка распределения или индекса, остается за механизмом хранения. Этот выбор может меняться между выполнениями без изменения в плане запроса .Это может звучать очень абстрактно, но может быть легче продемонстрировано с некоторыми запросами, использующими недокументированные функции к базе данных AdventureWorks2012 .
Запросы заимствованы с небольшой модификацией от Пола Уайта .
Наконец, просто чтобы прояснить, этот ответ о появлении упорядоченного набора результатов. Там нет гарантированного заказа презентации без верхнего уровня
ORDER BY
.Сканирование порядка размещения может происходить при множестве других обстоятельств, например, когда получена блокировка на уровне таблицы или база данных находится в режиме только для чтения. Параллелизм также может влиять на порядок, в котором возвращаются данные. Ключевым моментом является то
ORDER BY
, что без этого данные, в которых возвращаются данные, могут изменяться с течением времени в зависимости от конструкции.источник
... тогда вы не должны ожидать какого-либо заказа. Фактически, один и тот же запрос, выполняемый несколько раз, может возвращаться в другом порядке без предупреждения. Причина в том, что два ваших запроса - которые являются «разными» запросами, скорее всего, из-за разного текста запроса, а не из-за подсказки), имеют разные планы выполнения (и разница может быть незначительной, например, итератор, который выглядит одинаково в оба плана, но
ordered: true
только в одной или очень различном количестве оценочных строк, потому что один был скомпилирован до существенного изменения данных). Возможно также, что выполняется сканирование порядка распределения, как правильно заметил Джеймс в своем ответе.В любом случае, поскольку вы выполняете запрос без
ORDER BY
, SQL Server делает вывод, что вам не нужен порядок, и поэтому отключается и определяет наиболее эффективный способ возврата строк (его не волнует порядок, если вы этого не делаете. ).Позвольте мне сделать это очень ясно:
Если вы хотите или ожидаете определенный заказ, добавьте предложение ORDER BY
Это дошло до:
И я написал об этом в блоге:
Вот цитата из последнего, которая повторяет то, что я сказал в ответ на ваш комментарий об использовании подсказки индекса вместо
ORDER BY
предложения:Конор Каннингем - довольно умный парень, непосредственно ответственный за большую часть того, что делает SQL Server, когда обрабатывает запрос для вас - также написал об этом здесь:
Пожалуйста, прочитайте, а затем добавьте
ORDER BY
предложение к своим запросам, прежде чем жаловаться на другую или неожиданную сортировку.источник
Джеймс прекрасно объяснил, как это работает, но я хотел бы еще раз повторить одну вещь: если вы не используете функцию упорядочения, порядок строк в наборе результатов не определен . Если вам нужен определенный порядок, используйте явное
order by
предложение - если вы его не укажете, вы в основном говорите: «Меня не волнует порядок», а не «Упорядочить по кластерному индексу».источник