Хотя интересно спросить, как можно объяснить, что вы часто видите тот же порядок, я хотел бы указать, что никогда не стоит полагаться на неявный порядок, вызванный конкретной реализацией базовой базы данных двигатель. Другими словами, приятно знать, почему, но вы никогда не должны полагаться на это. Для 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
... .. .........
, как вы можете видеть, довольно сильно отличается от впервые мы столкнулись этот запрос. (Похоже, что строки упорядочены по второстепенному индексу, но у меня нет объяснений, почему это должно быть так).
В любом случае, нижняя строка - не полагаться на неявный порядок. Вы можете придумать объяснения, почему можно наблюдать определенный порядок, но даже тогда вы не можете всегда его предсказать (как в последнем случае), не имея интимного знания о состоянии реализации и времени выполнения.
+1 хороший вопрос – kevchadders