2010-01-11 9 views
10

Ich frage mich, wie SQL Server seine Daten sortiert. Ich habe festgestellt, dass, wenn ich eine Tabelle habe, die die Spalte "Id" nicht enthält und Sie Daten ohne "ORDER BY" auswählen, sortiert SQL Server nicht automatisch nach der primären Spalte.Wie sortiert der SQL Server Ihre Daten?

Weiß jemand, welche Regel SQL Server folgt, um seine Daten zu sortieren?

+1

+1 gute Frage – kevchadders

Antwort

20

Obwohl es gut ist, sich darüber zu wundern, wie es erklärt werden könnte, dass Sie oft die gleiche Reihenfolge sehen, möchte ich darauf hinweisen, dass es nie eine gute Idee ist, sich auf implizite Reihenfolge zu verlassen, die durch die spezielle Implementierung der zugrunde liegenden Datenbank verursacht wird Motor. Mit anderen Worten, es ist schön zu wissen, warum, aber Sie sollten sich nie darauf verlassen. Für MS SQL ist das einzige, was die Zeilen zuverlässig in einer bestimmten Reihenfolge liefert, eine explizite ORDER BY Klausel.

Unterschiedliche RDMBS-es verhalten sich nicht nur anders, sondern auch 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.

Auch wenn Sie Hintergrundinformationen über die Implementierung haben (zB: "Es gibt einen Clustered-Index, daher werden die Daten wahrscheinlich in der Reihenfolge des Clustered-Indexes zurückgegeben"), gibt es immer die Möglichkeit, dass es einen anderen gibt Mechanismus, den Sie nicht kennen, führt dazu, dass die Zeilen in einer anderen Reihenfolge zurückgegeben werden (Beispiel 1: "Wenn eine andere Sitzung gerade einen vollständigen Tabellenscan mit einer expliziten ORDER BY durchgeführt hat, wird ein nachfolgender vollständiger Scan versucht, zurückzukehren die Zeilen aus dem Cache "; ex2:" a GROUP BY kann durch Sortieren der Daten implementiert werden, was sich auf die Reihenfolge der zurückgegebenen Zeilen auswirkt "; ex3:" Wenn die ausgewählten Spalten alle in einem sekundären Index sind, der bereits im Speicher zwischengespeichert ist, Die Engine kann den sekundären Index anstelle der Tabelle scannen und höchstwahrscheinlich die Zeilen in der Reihenfolge des sekundären Indexes zurückgeben ").

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

Zuerst, SQL-Server starten (ich benutze 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 Zeuge, dass ein clusted Index wurde mit der primary key auf der id Säule zu unterstützen. Beispielsweise können Sie in Sql Server Management Studio die Strukturansicht verwenden und zum Indexordner unter Ihrer Tabelle navigieren.Dort sollten Sie einen Index, mit einem Namen wie sehen: PK__test_ord__3213E83F03317E3D (Clustered)

mit dieser Aussage die erste Zeile einfügen:

insert into test_order(name) 
select RAND() 

Insert mehr Zeilen durch diese Aussage 16-mal zu wiederholen:

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

Sie sollte jetzt 65536 Zeilen haben:

select COUNT(*) 
from test_order 

Wählen Sie jetzt alle Zeilen aus ohne einen Auftrag von:

select * 
from test_order 

Höchstwahrscheinlich werden die Ergebnisse im Auftrag des Primärschlüssels zurückgegeben (obwohl es keine Garantie). Hier ist das Ergebnis, das ich bekam (die in der Tat im Auftrag des Primärschlüssels ist):

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

(die # ist nicht eine Spalte, aber die Ordnungsposition der Zeile in dem Ergebnis)

Erstellen Sie jetzt ein sekundären Index auf der name Spalte:

create index idx_name on test_order(name) 

alle Zeilen auswählen, sondern nur abrufen, die name Spalte:

select name 
from test_order 

Höchstwahrscheinlich werden die Ergebnisse in der Reihenfolge des Sekundärindex idx_name zurückgegeben, da die Abfrage nur durch Scannen des Index aufgelöst werden kann (i.o.w. idx_name ist eine Abdeckung Index). Hier ist das Ergebnis, das ich in der Tat von name bekommen habe.

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

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

select * 
from test_order 

Hier ist das Ergebnis, das ich bekam:

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

wie Sie, ganz anders als das erste Mal sehen wir liefen diese Abfrage. (Es sieht so aus, als ob die Zeilen nach dem Sekundärindex geordnet sind, aber ich habe keine Erklärung, warum das so sein sollte).

Wie auch immer, das Endergebnis ist - verlassen Sie sich nicht auf implizite Reihenfolge. Sie können sich erklären, warum eine bestimmte Ordnung beobachtet werden kann, aber selbst dann können Sie sie nicht immer vorhersagen (wie im letzten Fall), ohne eine genaue Kenntnis von Implementierung und Laufzeit zu haben.

4

Wenn Sie keine ORDER BY-Klausel explizit angeben, gibt es keine garantierte Reihenfolge, in der die Ergebnisse sortiert werden. Es ist nicht einmal garantiert, dass sie auf dem Clustered-Index basiert.

Sie können ein Beispiel dafür in this article sehen.

0

AS SQL basiert auf Set thoery und Set garantiert keine Reihenfolge. Wenn Sie also keine bestimmte Bestellung explizit angeben, wird die Bestellung nicht garantiert.

0

Ich hatte eine ähnliche Erfahrung mit SQL Server, die Ergebnisse anders als ich erwartet zurücksendet. Ich fand, dass, wenn Sie einen Tabellenhinweis in der Auswahlanweisung angeben und den Namen des gruppierten Indexes geben, erhalten Sie die bestellten Resultate, wie Sie wünschen:

Verwandte Themen