2016-05-26 2 views
3

Я готовился к интервью и просто приходил к этому.Почему сортировка записей в таблице не соответствует кластерному индексу?

Я выполнившие следующие утверждения:

create table trial 
(
    Id int not null, 
    Name varchar(10) 
) 

alter table trial add constraint unq unique clustered (Name) 

alter table trial add constraint pk primary key nonclustered(Id) 

insert into trial values (1,'a'),(3,'d'),(5,'b'),(2,'c') 

select * from trial 

Результат показан здесь:

enter image description here

Мой вопрос: почему результат не сортируется согласно колонке имя, как имя столбца имеет кластерный индекс?

Результат:

1 a 
2 c 
3 d 
5 b 

Как использовать индекс для физической сортировки таблицы?

+0

Тег используемого dbms. (Индексы всегда более или менее специфичны для продукта.) – jarlh

+0

MS sql 2014 developer edition – Sagar

+0

Прочтите эту статью по этой теме. https://blogs.msdn.microsoft.com/conor_cunningham_msft/2008/08/27/no-seatbelt-expecting-order-without-order-by/ –

ответ

2

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

enter image description here

Вы можете заставить использовать кластерный индекс:

SELECT * FROM TRIAL WITH (INDEX(UNQ)) 

И вы, вероятно, получите:

enter image description here

и набор результатов:

Id Name 
1 a 
5 b 
2 c 
3 d 

Но вы не должны этого делать, потому что заказ по-прежнему не гарантируется. Если вы хотите, чтобы ваши результаты сортировались по некоторым столбцам, сделайте это явно!

Я скопировать фрагмент из книги Exam 70-461: Querying Microsoft SQL Server 2012, где вы можете получить хорошее объяснение:

Это может показаться, как выход отсортирован по EmpId, но это не гарантировано. Что может быть более запутанным, так это то, что если вы повторно выполняете запрос , кажется, что результат сохраняется в том же порядке; но опять же, это не гарантировано. Когда механизм базы данных (SQL Server в этом случае) обрабатывает этот запрос, он знает, что он может вернуть данные в любом порядке, потому что нет явной инструкции для вернуть данные в определенном порядке.Может быть, из-за оптимизации и других причин механизм базы данных SQL Server выбрал для обработки данных определенным образом на этот раз. Существует даже некоторая вероятность того, что такой выбор будет повторяться, если физические обстоятельства остаются неизменными. Но есть большая разница между , что может произойти из-за оптимизации и по другим причинам, и то, что на самом деле гарантировано.

Двигатель базы данных может быть, а иногда и делает изменения, которые могут повлиять на порядок, в котором строки возвращаются , зная, что это бесплатно. Примеры таких изменений в вариантах включают изменения в распределении данных, наличие физических структур, таких как индексы и доступность ресурсов , таких как процессоры и память. Кроме того, с изменениями в двигателе после обновления до более новой версии продукта или даже после приложения пакета обновления аспекты оптимизации могут измениться. В свою очередь, такие изменения могут повлиять, среди прочего, на порядок строк в .

Короче говоря, это не может быть подчеркнуто достаточно: Запрос, который не есть явное указание возвратить строки в определенном порядке не гарантирует порядок строк в результате , Когда вам нужна такая гарантия, единственный способ ее предоставить - это добавить предложение ORDER BY в запрос, и это в центре внимания следующего раздела.

EDIT на основе комментариев:

Дело в том, что даже если вы используете кластерный индекс может вернуться неупорядоченный набор. Предположим, у вас есть физический порядок кластеризованных ключей, например (1, 2, 3, 4, 5). Большую часть времени вы получите (1, 2, 3, 4, 5), но могут возникнуть ситуации, когда оптимизатор решает сделать Параллельное чтение и говорят, что он имеет 2 параллельных чтения, и он читает (1, 2, 3) и (4, 5). Теперь может случиться так, что сначала будет возвращен (4, 5), а затем можно вернуть (1, 2, 3). Если у вас нет order by, то механизм предложения не будет тратить свои ресурсы, заказывая этот набор и даст вам (4, 5, 1, 2, 3). Поэтому это объясняет, почему вы всегда должны убедиться, что у вас есть предложение order by, когда вы хотите заказать.

+0

Спасибо .. для этого уточнения. Фактически я знал, что физический порядок записей в таблице всегда соответствует кластерному индексу. .. Но я ошибся ... – Sagar

+0

@ Сагар, ты не был прав в этом. Я объясню более подробно в ответе. –

+0

thanx .. Я действительно доволен этим ответом. Параллельно читает ... правильно. – Sagar

4

Повторение: таблицы SQL представляют неупорядоченные комплекты. SQL-результирующие наборы: неупорядочен, если запрос не содержит предложение order by.

Итак, если вы хотите, данные в порядке, а затем использовать order by:

select t.* 
from trial t 
order by t.name; 

Если вы хотите получить результаты в определенном порядке, используйте order by. У SQL Server есть хороший оптимизатор. Если он может использовать индекс для запроса - чтобы избежать фактического сортировки, то он обычно будет использовать индекс.

+0

да, что я знаю .. почему записи в таблице не сортируются в соответствии с кластеризованный индекс? – Sagar

+0

Извините, у вас нет способа узнать, как записи сортируются в таблице. Вы можете видеть, как записи возвращаются вам, когда вы их запрашиваете, - и это чисто внутренняя неопределенная вещь SQL, если вы не запрашиваете указанный порядок. – Arvo

+0

@Sager. , , Проблема заключается не в сортировке таблиц. Проблема заключается в том, как работает запрос. Если вы сделали дамп данных на страницах, вы, вероятно, обнаружите, что данные действительно упорядочены на страницах данных. Тем не менее, запрос не должен уважать это. –

Смежные вопросы