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

Standardzeilenreihenfolge in der SELECT-Abfrage – SQL Server 2008 vs. SQL 2012

Sie müssen zurückgehen und ORDER BY hinzufügen Klauseln zu Ihrem Code, denn ohne sie ist die Reihenfolge niemals garantiert. In der Vergangenheit hatten Sie „Glück“, dass Sie immer die gleiche Reihenfolge erhalten haben, aber nicht, weil SQL Server 2008 dies sowieso garantiert hat. Es hatte höchstwahrscheinlich mit Ihren Indizes zu tun oder wie die Daten auf der Festplatte gespeichert wurden.

Wenn Sie beim Upgrade auf einen neuen Host umgezogen sind, könnte allein der Unterschied in der Hardwarekonfiguration die Art und Weise geändert haben, wie Ihre Abfragen ausgeführt werden. Ganz zu schweigen von der Tatsache, dass der neue Server die Statistiken für die Tabellen neu berechnet hätte und der Abfrageoptimierer von SQL Server 2012 wahrscheinlich etwas anders vorgeht als der in SQL Server 2008.

Es ist ein Trugschluss, dass Sie sich auf die Reihenfolge einer Ergebnismenge in SQL verlassen können, ohne die gewünschte Reihenfolge explizit anzugeben. SQL-Ergebnisse NIE eine Bestellung haben, auf die Sie sich verlassen können, ohne einen ORDER BY zu verwenden Klausel. SQL basiert auf der Mengenlehre. Abfrageergebnisse sind grundsätzlich Sets (oder Multisets).

Itzik Ben-Gan gibt in seinem Buch Microsoft SQL Server 2012 T-SQL Fundamentals

eine gute Beschreibung der Mengentheorie in Bezug auf SQL

Die Mengenlehre, die auf den Mathematiker Georg Cantor zurückgeht, ist eine der mathematischen Zweige, auf denen das relationale Modell basiert. Cantors Definition einer Menge folgt:

Mit einer „Menge“ meinen wir jede Sammlung M in ein Ganzes von bestimmten, unterschiedlichen Objekten m (die die „Elemente“ von M genannt werden) unserer Wahrnehmung oder unseres Denkens. - Joseph W. Dauben und Georg Cantor (Princeton University Press, 1990)

Nach einer gründlichen Erklärung der Begriffe in der Definition fährt Itzik dann fort:

Was Cantors Definition einer Menge auslässt, ist wahrscheinlich genauso wichtig wie das, was sie beinhaltet. Beachten Sie, dass die Definition keine Ordnung unter den Mengenelementen erwähnt. Die Reihenfolge, in der Mengenelemente aufgelistet werden, ist nicht wichtig. Die formale Notation zum Auflisten von Mengenelementen verwendet geschweifte Klammern:{a, b, c}. Da die Reihenfolge keine Rolle spielt, können Sie dieselbe Menge wie {b, a, c} oder {b, c, a} ausdrücken. Springen wir zu den Attributen (in SQL Spalten genannt), die den Header einer Relation (in SQL Tabelle genannt) bilden, soll ein Element durch seinen Namen identifiziert werden – nicht durch seine Ordinalposition. Betrachten Sie in ähnlicher Weise die Gruppe von Tupeln (von SQL als Zeilen bezeichnet), die den Hauptteil der Beziehung bilden; ein Element wird durch seine Schlüsselwerte identifiziert – nicht durch seine Position. Vielen Programmierern fällt es schwer, sich an die Vorstellung zu gewöhnen, dass es beim Abfragen von Tabellen keine Reihenfolge zwischen den Zeilen gibt. Mit anderen Worten, eine Abfrage einer Tabelle kann Zeilen in beliebiger Reihenfolge zurückgeben es sei denn, Sie verlangen ausdrücklich eine bestimmte Sortierung der Daten, etwa zu Präsentationszwecken.

Aber unabhängig von der akademischen Definition einer Menge hat selbst die Implementierung in SQL Server nie eine Ordnung in den Ergebnissen garantiert. Dieser MSDN-Blogbeitrag aus dem Jahr 2005 von einem Mitglied des Abfrageoptimierungsteams besagt, dass Sie sich überhaupt nicht auf die Reihenfolge von Zwischenoperationen verlassen sollten.

Die Neuordnungsregeln können und werden gegen diese Annahme verstoßen (und tun dies auch, wenn es für Sie als Entwickler unbequem ist;). Bitte haben Sie Verständnis dafür, dass wir, wenn wir Operationen neu ordnen, um einen effizienteren Plan zu finden, dazu führen können, dass sich das Sortierverhalten für Zwischenknoten im Baum ändert. Wenn Sie eine Operation in den Baum eingefügt haben, die eine bestimmte Zwischenordnung voraussetzt, kann sie brechen.

In diesem Blogbeitrag von Conor Cunningham (Architekt, SQL Server Core Engine) „No Seatbelt – Expecting Order without ORDER BY“ geht es um SQL Server 2008. Er hat eine Tabelle mit 20.000 Zeilen darin mit einem einzigen Index, der scheinbar immer Zeilen zurückgibt die gleiche Reihenfolge. Hinzufügen eines ORDER BY an die Abfrage ändert nicht einmal den Ausführungsplan, es ist also nicht so, als würde das Hinzufügen eines Plans die Abfrage teurer machen, wenn der Optimierer erkennt, dass er ihn nicht benötigt. Aber sobald er der Tabelle weitere 20.000 Zeilen hinzufügt, ändert sich plötzlich der Abfrageplan und jetzt verwendet er Parallelität und die Ergebnisse sind nicht mehr geordnet!

Das Schwierige daran ist, dass es für externe Benutzer keine vernünftige Möglichkeit gibt, zu wissen, wann sich ein Plan ändert. Der Raum aller Pläne ist riesig und es schmerzt im Kopf, darüber nachzudenken. Der Optimierer von SQL Server ändert Pläne, sogar für einfache Abfragen, wenn sich genügend Parameter ändern. Sie können Glück haben und keine Planänderung haben, oder Sie können einfach nicht an dieses Problem denken und ein ORDER BY hinzufügen.

Wenn Sie mehr Überzeugung brauchen, lesen Sie einfach diese Beiträge:

  • Ohne ORDER BY gibt es keine Standardsortierreihenfolge. - Alexander Kusnezow
  • Ordnen Sie im Gericht! -Thomas Kyte
  • Reihenfolge einer Ergebnismenge in SQL - Timothy Wiseman