sql >> Databáze >  >> RDS >> Sqlserver

Jak sql server třídí vaše data?

I když je dobré přemýšlet o tom, jak by se dalo vysvětlit, že často vidíte stejné pořadí, rád bych zdůraznil, že nikdy není dobrý nápad spoléhat se na implicitní pořadí způsobené konkrétní implementací základního databázového stroje. Jinými slovy, je hezké vědět proč, ale nikdy byste na to neměli spoléhat. Pro MS SQL je jedinou věcí, která spolehlivě dodává řádky v určitém pořadí, explicitní ORDER BY doložka.

Nejenže se různé RDMBS chovají odlišně, jedna konkrétní instance se může chovat odlišně kvůli aktualizaci (záplatě). Nejen to, vliv může mít i stav softwaru RDBMS:„teplá“ databáze se chová jinak než „studená“, malý stůl se chová jinak než velký.

I když máte základní informace o implementaci (např.:„existuje seskupený index, takže je pravděpodobné, že data budou vrácena podle pořadí seskupeného indexu“), vždy existuje možnost, že existuje jiný mechanismus, který nemáte. nevím o tom, že řádky budou vráceny v jiném pořadí (např. 1:"pokud jiná relace právě provedla úplné prohledání tabulky s explicitním ORDER BY sada výsledků mohla být uložena do mezipaměti; následná úplná kontrola se pokusí vrátit řádky z mezipaměti"; ex2:"a GROUP BY lze implementovat setříděním dat, čímž se ovlivní pořadí, ve kterém jsou řádky vráceny"; ex3:"Pokud jsou všechny vybrané sloupce v sekundárním indexu, který je již uložen v paměti, stroj může skenovat sekundární index namísto tabulky, s největší pravděpodobností vrací řádky podle pořadí sekundárního indexu").

Zde je velmi jednoduchý test, který ilustruje některé z mých bodů.

Nejprve spusťte SQL server (používám 2008). Vytvořte tuto tabulku:

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

Prohlédněte si tabulku a přesvědčte se, že byl vytvořen seskupený index pro podporu primary key na id sloupec. Například v SQL Server Management Studio můžete použít stromové zobrazení a přejít do složky indexů pod vaší tabulkou. Zde byste měli vidět jeden index s názvem jako:PK__test_ord__3213E83F03317E3D (Clustered)

Vložte první řádek s tímto příkazem:

insert into test_order(name)
select RAND()

Vložte další řádky opakováním tohoto příkazu 16krát:

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

Nyní byste měli mít 65536 řádků:

select COUNT(*) 
from   test_order

Nyní vyberte všechny řádky bez použití pořadí podle:

select *
from   test_order

S největší pravděpodobností budou výsledky vráceny podle pořadí primárního klíče (ačkoli neexistuje žádná záruka). Zde je výsledek, který jsem dostal (který je skutečně podle pořadí primárního klíče):

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

(# není sloupec, ale pořadová pozice řádku ve výsledku)

Nyní vytvořte sekundární index pro name sloupec:

create index idx_name on test_order(name)

Vyberte všechny řádky, ale načtěte pouze name sloupec:

select name
from   test_order

S největší pravděpodobností budou výsledky vráceny v pořadí sekundárního indexu idx_name, protože dotaz lze vyřešit pouze skenováním indexu (i.o.w. idx_name je krytí index). Zde je výsledek, který jsem dostal, který je skutečně v pořadí name .

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

Nyní znovu vyberte všechny sloupce a všechny řádky:

select * 
from test_order

Zde je výsledek, který jsem dostal:

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

jak vidíte, zcela odlišné od prvního spuštění tohoto dotazu. (Vypadá to, že řádky jsou seřazeny podle sekundárního indexu, ale nemám vysvětlení, proč by tomu tak mělo být).

Každopádně podstata zní – nespoléhejte na implicitní řád. Můžete si vymyslet vysvětlení, proč lze konkrétní objednávku pozorovat, ale i tak ji nemůžete vždy předvídat (jako v druhém případě), aniž byste měli důvěrnou znalost implementace a stavu běhu.



  1. aktualizace řádků namísto vytváření nové databáze záznamů pro Android

  2. Co je rychlejší:Mnoho řádků nebo mnoho sloupců?

  3. Vložte obsah souboru do sloupce tabulky MySQL

  4. Pochopení Pivot Operatoru v SQL