Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Wie sortiert der SQL-Server Ihre Daten?

Obwohl es gut ist, sich zu fragen, wie es erklärt werden könnte, dass Sie oft dieselbe Reihenfolge sehen, möchte ich darauf hinweisen, dass es niemals eine gute Idee ist, sich auf die implizite Reihenfolge zu verlassen, die durch die bestimmte Implementierung der zugrunde liegenden Datenbank-Engine verursacht wird. Mit anderen Worten, es ist schön zu wissen, warum, aber Sie sollten sich niemals darauf verlassen. Für MS SQL ist das Einzige, was die Zeilen zuverlässig in einer bestimmten Reihenfolge liefert, ein explizites ORDER BY Klausel.

Nicht nur, dass sich verschiedene RDMBS-es unterschiedlich verhalten, eine bestimmte Instanz kann sich aufgrund eines Updates (Patch) anders verhalten. Nicht nur das, auch der Zustand der RDBMS-Software kann Auswirkungen haben:Eine "warme" Datenbank verhält sich anders als eine "kalte", eine kleine Tabelle verhält sich anders als eine große.

Selbst wenn Sie Hintergrundinformationen über die Implementierung haben (z. B.:„Es gibt einen Clustered-Index, daher werden die Daten wahrscheinlich in der Reihenfolge des Clustered-Index zurückgegeben“), besteht immer die Möglichkeit, dass es einen anderen Mechanismus gibt, den Sie nicht kennen. Nicht wissen, dass dies dazu führt, dass die Zeilen in einer anderen Reihenfolge zurückgegeben werden (Bsp. 1:„wenn eine andere Sitzung gerade einen vollständigen Tabellenscan mit einem expliziten ORDER BY durchgeführt hat das Resultset wurde möglicherweise zwischengespeichert; ein nachfolgender vollständiger Scan versucht, die Zeilen aus dem Cache zurückzugeben"; ex2:"a GROUP BY kann durch Sortieren der Daten implementiert werden, was sich auf die Reihenfolge auswirkt, in der die Zeilen zurückgegeben werden"; ex3:"Wenn sich die ausgewählten Spalten alle in einem sekundären Index befinden, der bereits im Speicher zwischengespeichert ist, scannt die Engine möglicherweise den sekundären Index anstelle der Tabelle, höchstwahrscheinlich Rückgabe der Zeilen in der Reihenfolge des sekundären Index").

Hier ist ein sehr einfacher Test, der einige meiner Punkte veranschaulicht.

Starten Sie zuerst den SQL-Server (ich verwende 2008). Erstellen Sie diese Tabelle:

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

Untersuchen Sie die Tabelle und sehen Sie, dass ein gruppierter Index erstellt wurde, um den primary key zu unterstützen auf der id Säule. In SQL Server Management Studio können Sie beispielsweise die Baumansicht verwenden und zum Indexordner unter Ihrer Tabelle navigieren. Dort sollten Sie einen Index sehen, mit einem Namen wie:PK__test_ord__3213E83F03317E3D (Clustered)

Fügen Sie die erste Zeile mit dieser Anweisung ein:

insert into test_order(name)
select RAND()

Fügen Sie weitere Zeilen ein, indem Sie diese Anweisung 16 Mal wiederholen:

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

Sie sollten jetzt 65536 Zeilen haben:

select COUNT(*) 
from   test_order

Wählen Sie nun alle Zeilen aus, ohne eine Reihenfolge zu verwenden:

select *
from   test_order

Höchstwahrscheinlich werden die Ergebnisse in der Reihenfolge des Primärschlüssels zurückgegeben (obwohl es keine Garantie gibt). Hier ist das Ergebnis, das ich erhalten habe (das tatsächlich nach Primärschlüssel sortiert ist):

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

(Das # ist keine Spalte, sondern die Ordinalposition der Zeile im Ergebnis)

Erstellen Sie nun einen sekundären Index für name Spalte:

create index idx_name on test_order(name)

Wählen Sie alle Zeilen aus, aber rufen Sie nur den name ab Spalte:

select name
from   test_order

Höchstwahrscheinlich werden die Ergebnisse in der Reihenfolge des sekundären Index idx_name zurückgegeben, da die Abfrage gelöst werden kann, indem nur der Index gescannt wird (z. B. idx_name ist eine Hülle Index). Hier ist das Ergebnis, das ich erhalten habe, das tatsächlich in der Reihenfolge name ist .

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

Wählen Sie nun wieder alle Spalten und alle Zeilen aus:

select * 
from test_order

Hier ist das Ergebnis, das ich bekommen habe:

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

wie Sie sehen können, ganz anders als beim ersten Mal, als wir diese Abfrage ausgeführt haben. (Es sieht so aus, als ob die Zeilen nach dem sekundären Index geordnet sind, aber ich habe keine Erklärung, warum das so sein sollte).

Wie auch immer, die Quintessenz ist - verlassen Sie sich nicht auf implizite Reihenfolge. Sie können sich Erklärungen ausdenken, warum eine bestimmte Reihenfolge beobachtet werden kann, aber selbst dann können Sie sie nicht immer vorhersagen (wie im letzteren Fall), ohne genaue Kenntnisse der Implementierung und des Laufzeitstatus zu haben.