Warum SQL Server keine Sortierergebnisse ohne ORDER BY garantiert

Hallo wieder. Im Juni startet OTUS erneut den Kurs „MS SQL Server Developer“ . Traditionell beginnen wir am Vorabend des Kursbeginns , Material zu diesem Thema mit Ihnen zu teilen.




Wenn Ihre Abfrage ORDER BY nicht enthält, können Sie nicht sicher sein, dass sich die Sortierung der Ergebnisse im Laufe der Zeit nicht ändert.

Natürlich ist zunächst alles ziemlich vorhersehbar, aber wenn Änderungen auftreten (in Indizes, Tabellen, Serverkonfiguration, Datenmenge), kann es zu unangenehmen Überraschungen kommen.

Beginnen wir mit etwas Einfachem: Führen Sie ein SELECT für die Users-Tabelle der Stack Overflow-Datenbank aus. Diese Tabelle enthält einen Clusterindex für die ID-Spalte, der bei eins beginnt und auf eine Billion ansteigt. Für diese Abfrage werden die Daten in der Reihenfolge des Clustered-Index zurückgegeben:



Wenn Sie jedoch einen Index für DisplayName und Location erstellen, entscheidet sich SQL Server plötzlich für die Verwendung eines neuen Index, nicht eines Clustered-Index:



Hier ist der Ausführungsplan:



Warum SQL Server diesen Index verwendet hat, obwohl er nicht sortiert werden musste nach Anzeigename und Standort? Weil dieser Index die kleinste Kopie der Daten ist, die abgerufen werden müssen. Schauen wir uns die Größe der Indizes an mit sp_BlitzIndex:



Der Clustered Index (CX / PK) hat ungefähr 8,9 Millionen Zeilen und eine Größe von 1,1 GB .

Im nicht gruppierten Index für DisplayName beträgt der Speicherort ebenfalls etwa 8,9 Millionen Zeilen, seine Größe beträgt jedoch nur 368 MB . Wenn Sie einen Scan durchführen müssen, um die Abfrageergebnisse zu erhalten, wählen Sie die kleinste Datenquelle aus, da diese schneller ist. Aus diesem Grund hat SQL Server dies getan.

"Ja, aber meine Anfrage enthält WO."


Ok, jetzt, da wir einen Index für DisplayName und Location haben, versuchen wir eine Abfrage, die nach einem bestimmten Namen (DisplayName) sucht. Die Ergebnisse sind nach Anzeigename sortiert:



Der Ausführungsplan zeigt, dass der Index von Anzeigename und Speicherort verwendet wird.



Wenn Sie jedoch einen anderen Wert betrachten, werden die Ergebnisse nicht mehr nach Anzeigename sortiert:



SQL Server hat festgestellt, dass Alex einen wesentlich vernünftigeren Clustered-Index hat Scannen statt Indexsuche + Schlüsselsuche:



Selbst in diesen wirklich einfachen Fällen können Sie nicht garantieren, dass SQL Server immer die erwartete Datenkopie verwendet.

In letzter Zeit bin ich auf viel kompliziertere Fälle gestoßen:

  • Entfernen des in der Abfrage verwendeten Index
  • (Forced Parameterization), , SQL Server
  • (Compatibility Level) (Cardinality Estimator), .



.



All Articles