2010-01-11 4 views
10

Мне было интересно, как SQL Server сортирует данные. Я заметил, что если у меня есть таблица, которая не содержит столбец «Id», и вы выбираете данные без «ORDER BY», сервер sql автоматически не сортирует по основному столбцу.Как сервер SQL сортирует данные?

Кто-нибудь знает, что следует за сервером SQL Server для сортировки данных?

+1

+1 хороший вопрос – kevchadders

ответ

20

Хотя интересно спросить, как можно объяснить, что вы часто видите тот же порядок, я хотел бы указать, что никогда не стоит полагаться на неявный порядок, вызванный конкретной реализацией базовой базы данных двигатель. Другими словами, приятно знать, почему, но вы никогда не должны полагаться на это. Для MS SQL единственное, что надежно доставляет строки в определенном порядке, - это явное предложение ORDER BY.

Не только разные RDMBS-es ведут себя по-другому, один конкретный экземпляр может вести себя по-разному из-за обновления (патча). Мало того, что даже состояние программного обеспечения РСУБД может оказать влияние: «теплая» база данных ведет себя иначе, чем «холодная», небольшая таблица ведет себя не так, как большая.

Даже если у вас есть справочная информация о реализации (например: «есть кластеризованный индекс, поэтому, скорее всего, данные будут возвращены по порядку кластерного индекса»), всегда есть вероятность, что есть еще одна механизм, о котором вы не знаете, заставляет строки возвращаться в другом порядке (ex1: ", если другой сеанс просто выполнил полное сканирование таблицы с явным ORDER BY, набор результатов может быть кэширован, последующее полное сканирование попытается вернуть строки из кэша "; ex2:" a GROUP BY могут быть реализованы путем сортировки данных, что влияет на порядок возврата строк "; ex3:" Если выбранные столбцы находятся во вторичном индексе, который уже кэшируется в памяти, двигатель может сканировать вторичный индекс вместо таблицы, скорее всего, возвращая строки по порядку вторичного индекса »).

Вот очень простой тест, который иллюстрирует некоторые мои вопросы.

Во-первых, запуск SQL-сервера (я использую 2008). Создайте эту таблицу:

create table test_order (
    id int not null identity(1,1) primary key 
, name varchar(10) not null 
) 

Осмотрите стол и свидетельство о том, что clusted индекс был создан для поддержки primary key на id колонки. Например, в студии управления сервером sql вы можете использовать древовидное представление и перейти к папке индексов под вашей таблицей.Там вы должны увидеть один индекс, с именем, как: PK__test_ord__3213E83F03317E3D (Clustered)

Вставьте первую строку с этим утверждением:

insert into test_order(name) 
select RAND() 

Вставка больше строк, повторяя это заявление, 16 раз:

insert into test_order(name) 
select RAND() 
from test_order 

You должен теперь иметь 65536 строк:

select COUNT(*) 
from test_order 

Теперь, выберите все строки без использования заказа:

select * 
from test_order 

Скорее всего, результаты будут возвращены по порядку первичного ключа (хотя нет никакой гарантии). Вот результат я получил (это действительно приказом первичного ключа):

#  id name 
1  1  0.605831 
2  2  0.517251 
3  3  0.52326 
.  .  ....... 
65536 65536 0.902214 

(# не столбец, а порядковое положение строки в результате)

Теперь создайте вторичный индекс на name колонке:

create index idx_name on test_order(name) 

Выберите все строки, но получить только name колонки:

select name 
from test_order 

Скорее всего, результаты будут возвращены по порядку вторичного индекса idx_name, так как запрос может быть разрешен только при сканировании индекса (i.o.w. idx_name - покрытие индекс). Вот результат, который я получил, который действительно по порядку name.

#  name 
1  0.0185732 
2  0.0185732 
.  ......... 
65536 0.981894 

Теперь выберите все столбцы и все строки снова:

select * 
from test_order 

Вот результат я получил:

#  id name 
1  17 0.0185732 
2  18 0.0185732 
3  19 0.0185732 
... .. ......... 

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

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

4

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

Вы можете увидеть пример этого в this article.

0

AS SQL основан на Set thoery, и Set не гарантирует никакого заказа, поэтому, если вы не укажете конкретный заказ явно, заказ не будет гарантирован.

0

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

select * from test_order WITH (INDEX([ClusteredIndexName])) 
Смежные вопросы