sql >> Database teknologi >  >> RDS >> Sqlserver

Hvordan sorterer sql server dine data?

Selvom det er godt at undre sig over, hvordan det kan forklares, at du ofte ser den samme rækkefølge, vil jeg gerne påpege, at det aldrig er en god idé at stole på implicit rækkefølge forårsaget af den særlige implementering af den underliggende databasemotor. Med andre ord, det er rart at vide hvorfor, men du bør aldrig stole på det. For MS SQL er det eneste, der pålideligt leverer rækkerne i en bestemt rækkefølge, en eksplicit ORDER BY klausul.

Ikke alene opfører forskellige RDMBS-er sig forskelligt, én bestemt instans kan opføre sig anderledes på grund af en opdatering (patch). Ikke nok med det, selv tilstanden af ​​RDBMS-softwaren kan have en indflydelse:en "varm" database opfører sig anderledes end en "kold", en lille tabel opfører sig anderledes end en stor.

Selv hvis du har baggrundsinformation om implementeringen (f.eks.:"der er et klynget indeks, så det er sandsynligt, at dataene vil blive returneret efter rækkefølge af det klyngede indeks"), er der altid en mulighed for, at der er en anden mekanisme, du gør' ikke vide om, at det forårsager, at rækkerne returneres i en anden rækkefølge (ex1:"hvis en anden session lige har lavet en fuld tabelscanning med en eksplicit ORDER BY resultatsættet kan være blevet cachelagt; en efterfølgende fuld scanning vil forsøge at returnere rækkerne fra cachen"; ex2:"a GROUP BY kan implementeres ved at sortere dataene og dermed påvirke rækkefølgen, som rækkerne returneres"; ex3:"Hvis de valgte kolonner alle er i et sekundært indeks, der allerede er cachelagret i hukommelsen, kan motoren scanne det sekundære indeks i stedet for tabellen, mest sandsynligt at returnere rækkerne efter rækkefølgen af ​​det sekundære indeks").

Her er en meget simpel test, der illustrerer nogle af mine pointer.

Først skal du starte SQL-serveren (jeg bruger 2008). Opret denne tabel:

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

Undersøg tabellen og vidne om, at et klynget indeks blev oprettet for at understøtte den primary keyid kolonne. For eksempel, i sql server management studio, kan du bruge trævisningen og navigere til mappen indekser under din tabel. Der skulle du se ét indeks med et navn som:PK__test_ord__3213E83F03317E3D (Clustered)

Indsæt den første række med denne sætning:

insert into test_order(name)
select RAND()
 

Indsæt flere rækker ved at gentage denne sætning 16 gange:

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

Du skulle nu have 65536 rækker:

select COUNT(*) 
from   test_order
 

Vælg nu alle rækker uden at bruge en ordre ved at:

select *
from   test_order
 

Mest sandsynligt vil resultaterne blive returneret efter ordre fra den primære nøgle (selvom der ikke er nogen garanti). Her er resultatet, jeg fik (som faktisk er i rækkefølge efter primær nøgle):

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

(# er ikke en kolonne, men rækkens ordensposition i resultatet)

Opret nu et sekundært indeks på name kolonne:

create index idx_name on test_order(name)
 

Vælg alle rækker, men hent kun name kolonne:

select name
from   test_order
 

Mest sandsynligt vil resultaterne blive returneret efter rækkefølgen af ​​det sekundære indeks idx_name, da forespørgslen kan løses ved kun at scanne indekset (i.o.w. idx_name er en dækning indeks). Her er resultatet, jeg fik, som faktisk er efter rækkefølgen name .

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

Vælg nu alle kolonner og alle rækker igen:

select * 
from test_order
 

Her er resultatet, jeg fik:

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

som du kan se, helt anderledes end første gang, vi kørte denne forespørgsel. (Det ser ud til, at rækkerne er ordnet efter det sekundære indeks, men jeg har ikke en forklaring på, hvorfor det skulle være sådan).

I hvert fald, bundlinjen er - stol ikke på implicit orden. Du kan tænke på forklaringer på, hvorfor en bestemt rækkefølge kan observeres, men selv da kan du ikke altid forudsige den (som i sidstnævnte tilfælde) uden at have indgående kendskab til implementering og runtime-tilstand.



  1. Forbindelsestimeout for SQL-server

  2. Hvor kan jeg få SQL til standard Oracles HR-skema?

  3. PostgreSQL-fejl 42501:Tilladelse nægtet til skema

  4. MS Excel - sammenføj eksterne (SQL) data med lokal tabel (ark)