sql >> Database >  >> RDS >> Sqlserver

Hoe sorteert de sql-server uw gegevens?

Hoewel het goed is om je af te vragen hoe het kan worden verklaard dat je vaak dezelfde volgorde ziet, wil ik je erop wijzen dat het nooit een goed idee is om te vertrouwen op een impliciete volgorde die wordt veroorzaakt door de specifieke implementatie van de onderliggende database-engine. Met andere woorden, het is leuk om te weten waarom, maar je moet er nooit op vertrouwen. Voor MS SQL is het enige dat de rijen betrouwbaar in een bepaalde volgorde levert, een expliciete ORDER BY clausule.

Niet alleen gedragen verschillende RDMBS-en zich anders, een bepaalde instantie kan zich door een update (patch) ook anders gedragen. Niet alleen dat, zelfs de status van de RDBMS-software kan een impact hebben:een "warme" database gedraagt ​​zich anders dan een "koude", een kleine tabel gedraagt ​​zich anders dan een grote.

Zelfs als u achtergrondinformatie heeft over de implementatie (bijvoorbeeld:"er is een geclusterde index, dus het is waarschijnlijk dat de gegevens worden geretourneerd in opdracht van de geclusterde index"), is er altijd een mogelijkheid dat er een ander mechanisme is dat u niet' Als u hiervan op de hoogte bent, worden de rijen in een andere volgorde geretourneerd (bijv. 1:"als een andere sessie zojuist een volledige tabelscan heeft uitgevoerd met een expliciete ORDER BY de resultatenset is mogelijk in de cache opgeslagen; een volgende volledige scan zal proberen de rijen terug te halen uit de cache"; ex2:"a GROUP BY kan worden geïmplementeerd door de gegevens te sorteren, waardoor de volgorde waarin de rijen worden geretourneerd wordt beïnvloed"; ex3:"Als de geselecteerde kolommen zich allemaal in een secundaire index bevinden die al in het geheugen is opgeslagen, kan de engine de secundaire index scannen in plaats van de tabel, hoogstwaarschijnlijk de rijen retourneren in volgorde van de secundaire index").

Hier is een heel eenvoudige test die enkele van mijn punten illustreert.

Start eerst de SQL-server op (ik gebruik 2008). Maak deze tabel:

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

Bekijk de tabel en zie dat er een geclusterde index is gemaakt om de primary key te ondersteunen op de id kolom. In sql server management studio kunt u bijvoorbeeld de boomstructuur gebruiken en naar de map indexen onder uw tabel navigeren. Daar zou je één index moeten zien, met een naam als:PK__test_ord__3213E83F03317E3D (Clustered)

Voeg de eerste rij in met deze verklaring:

insert into test_order(name)
select RAND()

Voeg meer rijen in door deze uitspraak 16 keer te herhalen:

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

Je zou nu 65536 rijen moeten hebben:

select COUNT(*) 
from   test_order

Selecteer nu alle rijen zonder een volgorde te gebruiken op:

select *
from   test_order

Hoogstwaarschijnlijk zullen de resultaten worden geretourneerd in volgorde van de primaire sleutel (hoewel er geen garantie is). Dit is het resultaat dat ik heb gekregen (wat inderdaad in opdracht van de primaire sleutel is):

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

(de # is geen kolom maar de ordinale positie van de rij in het resultaat)

Maak nu een secundaire index op de name kolom:

create index idx_name on test_order(name)

Selecteer alle rijen, maar haal alleen de name op kolom:

select name
from   test_order

Hoogstwaarschijnlijk zullen de resultaten worden geretourneerd in volgorde van de secundaire index idx_name, aangezien de query kan worden opgelost door alleen de index te scannen (i.o.w. idx_name is een bedekkende inhoudsopgave). Dit is het resultaat dat ik heb gekregen, en dat is inderdaad in opdracht van name .

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

Selecteer nu alle kolommen en alle rijen opnieuw:

select * 
from test_order

Dit is het resultaat dat ik heb:

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

zoals je kunt zien, heel anders dan de eerste keer dat we deze zoekopdracht uitvoerden. (Het lijkt erop dat de rijen zijn geordend op de secundaire index, maar ik heb geen verklaring waarom dat zo zou moeten zijn).

Hoe dan ook, de bottom line is - vertrouw niet op impliciete volgorde. Je kunt verklaringen bedenken waarom een ​​bepaalde volgorde kan worden waargenomen, maar zelfs dan kun je het niet altijd voorspellen (zoals in het laatste geval) zonder grondige kennis van implementatie en runtime-status.



  1. Hoe SET ROWCOUNT werkt in SQL Server

  2. SQL-query om kolomtellingen om te zetten in rijtellingen

  3. Oracle-update loopt vast

  4. Hoe de JJJJMMDD-datum te valideren die is opgegeven als parameter PL/SQL