Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Jak serwer sql sortuje twoje dane?

Chociaż dobrze jest zastanowić się, jak można wyjaśnić, że często widzisz tę samą kolejność, chciałbym zaznaczyć, że nigdy nie jest dobrym pomysłem poleganie na niejawnej kolejności spowodowanej konkretną implementacją bazowego silnika bazy danych. Innymi słowy, miło jest wiedzieć dlaczego, ale nigdy nie powinieneś na tym polegać. W przypadku MS SQL jedyną rzeczą, która niezawodnie dostarcza wiersze w określonej kolejności, jest jawne ORDER BY klauzula.

Nie tylko różne RDMBS-y zachowują się inaczej, ale jedna konkretna instancja może zachowywać się inaczej z powodu aktualizacji (poprawki). Mało tego, nawet stan oprogramowania RDBMS może mieć wpływ:„ciepła” baza danych zachowuje się inaczej niż „zimna”, mała tabela zachowuje się inaczej niż duża.

Nawet jeśli masz podstawowe informacje o implementacji (np.:„istnieje indeks klastrowy, więc prawdopodobnie dane zostaną zwrócone według kolejności indeksu klastrowego”), zawsze istnieje możliwość, że istnieje inny mechanizm, którego nie używasz Wiedza o tym powoduje, że wiersze są zwracane w innej kolejności (np.:"jeśli inna sesja właśnie wykonała pełne skanowanie tabeli z jawnym ORDER BY zestaw wyników mógł zostać zbuforowany; kolejne pełne skanowanie będzie próbowało zwrócić wiersze z pamięci podręcznej"; ex2:"a GROUP BY może być realizowane poprzez sortowanie danych, co ma wpływ na kolejność zwracania wierszy”; przykład3:„Jeśli wybrane kolumny znajdują się w indeksie wtórnym, który jest już zbuforowany w pamięci, silnik może skanować indeks wtórny zamiast tabeli, najprawdopodobniej zwraca wiersze według kolejności indeksu wtórnego").

Oto bardzo prosty test, który ilustruje niektóre z moich punktów.

Najpierw uruchom serwer SQL (używam 2008). Utwórz tę tabelę:

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

Sprawdź tabelę i zobacz, że utworzono indeks klastrowy do obsługi primary key na id kolumna. Na przykład w sql server management studio można użyć widoku drzewa i przejść do folderu indexs pod tabelą. Powinieneś tam zobaczyć jeden indeks o nazwie:PK__test_ord__3213E83F03317E3D (Clustered)

Wstaw pierwszy wiersz z następującym stwierdzeniem:

insert into test_order(name)
select RAND()

Wstaw więcej wierszy, powtarzając to stwierdzenie 16 razy:

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

Powinieneś teraz mieć 65536 wierszy:

select COUNT(*) 
from   test_order

Teraz wybierz wszystkie wiersze bez użycia kolejności:

select *
from   test_order

Najprawdopodobniej wyniki zostaną zwrócone według kolejności klucza podstawowego (chociaż nie ma gwarancji). Oto wynik, który otrzymałem (który rzeczywiście jest uporządkowany według klucza podstawowego):

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

(# nie jest kolumną, ale porządkową pozycją wiersza w wyniku)

Teraz utwórz dodatkowy indeks na name kolumna:

create index idx_name on test_order(name)

Zaznacz wszystkie wiersze, ale pobierz tylko name kolumna:

select name
from   test_order

Najprawdopodobniej wyniki zostaną zwrócone według kolejności indeksu dodatkowego idx_name, ponieważ zapytanie może zostać rozwiązane tylko poprzez skanowanie indeksu (np. idx_name to przykrycie indeks). Oto wynik, który otrzymałem, rzeczywiście według kolejności name .

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

Teraz ponownie zaznacz wszystkie kolumny i wszystkie wiersze:

select * 
from test_order

Oto wynik, który otrzymałem:

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

jak widać, zupełnie inaczej niż przy pierwszym uruchomieniu tego zapytania. (Wygląda na to, że wiersze są uporządkowane według indeksu wtórnego, ale nie mam wyjaśnienia, dlaczego tak powinno być).

W każdym razie najważniejsze jest - nie polegaj na ukrytym porządku. Możesz wymyślić wyjaśnienia, dlaczego można zaobserwować określoną kolejność, ale nawet wtedy nie zawsze możesz ją przewidzieć (jak w tym drugim przypadku) bez gruntownej wiedzy na temat implementacji i stanu środowiska wykonawczego.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wydajność zmiennych tabel w SQL Server

  2. Pobieranie błędu automatycznego tworzenia pliku bazy danych SQLExpress dla witryny korzystającej z programu AspNetSqlMembershipProvider, ale ciąg połączenia jest z programem SQL Server 2005

  3. Suma podzapytań w SQL Server

  4. Jak serializować duży wykres obiektu .NET do obiektu BLOB programu SQL Server bez tworzenia dużego bufora?

  5. Filtrowanie według opcji OFFSET-FETCH w zapytaniu Select — samouczek SQL Server / TSQL, część 118