web-dev-qa-db-de.com

Bewährte SQL-Methode zum Umgang mit der Standardsortierreihenfolge

Ich habe viel SQL-Code gelesen, es scheint, als würde der Entwickler davon ausgehen, dass die Standardsortierreihenfolge immer gilt. Beim Erstellen einer HTML-Auswahlliste würden sie beispielsweise SELECT id, name FROM table ohne eine ORDER BY-Klausel ausgeben.

Aus meiner eigenen Erfahrung scheint es, als würde dbms immer Daten mit FIFO bestellen, wenn keine ORDER BY-Klausel und kein Index angegeben ist. Die Bestellung ist jedoch nicht garantiert. Aber ich habe noch nie gesehen, wie ein DBMS Daten umsortiert, wenn sich an der Tabelle nichts geändert hat.

Haben Sie jemals erlebt, dass ein Datenbanksystem Daten in einer nicht deterministischen Reihenfolge auswählt, wenn sich die Tabelle nicht ändert?

Ist es am besten, immer eine ORDER BY-Klausel zu setzen? 

29
Yada

Es gibt keine Standardsortierreihenfolge. Selbst wenn die Tabelle einen gruppierten Index hat, können Sie die Ergebnisse nicht in dieser Reihenfolge erhalten. Sie müssen eine order by-Klausel verwenden, wenn Sie eine bestimmte Bestellung wünschen.

46
HLGEM

Wie in den anderen Plakaten erwähnt, sagt der SQL-Standard, wenn Sie keine Sortierreihenfolge angeben, dass die Ergebnisse in jeder Reihenfolge ablaufen können, die der Abfrageprozessor am sinnvollsten und effizientesten findet. 

Angenommen, Sie führen eine einfache ungeordnete SELECT-Anweisung für alle Zeilen einer CUSTOMER-Tabelle aus, die keine Indizes und keinen Primärschlüssel enthält. Es ist durchaus möglich und sogar wahrscheinlich, dass der Abfrageprozessor einen direkten Tabellenscan durchführt und die Zeilen in der Reihenfolge erzeugt, in der sie ursprünglich eingefügt wurden (wodurch Sie das Verhalten von FIFO erhalten haben).

Wenn Sie dann einen Index für die STATE- und CITY-Felder hinzufügen (in dieser Reihenfolge) und dann nach WHERE STATE = 'NY' abfragen, entscheidet der Abfrageprozessor möglicherweise, dass es effizienter ist, die Indexeinträge nach STATE = 'NY' zu durchsuchen, als einen vollständigen Tabellenscan durchzuführen . In diesem Fall werden die Zeilen wahrscheinlich in der Reihenfolge STATE, CITY ausgeführt.

Auch das ist nicht sicher. Wenn der Abfrageprozessor beispielsweise Statistiken gesammelt hat, die zeigen, dass fast alle STATE-Werte in Ihrer Tabelle "NY" sind (möglicherweise, weil die Datenbank für ein in Albany ansässiges Verleihgeschäft bestimmt ist), könnte der Tabellenscan tatsächlich billiger sein als der Index-Scan, und Sie sehen wieder FIFO.

Es ist eine gute Idee, einige Grundlagen zu erfahren, wie Ihre Datenbank ihre Abfragen plant. Sie können die Anweisung EXPLAIN verwenden, um zu sehen, wie Ihr DBMS eine bestimmte Abfrage ausführt, und diese anschließend zur Optimierung Ihrer Abfrage in einigen Fällen nach Größenordnungen verwenden. Dies ist ein faszinierender und nützlicher Bereich zum Lernen.

17
Jim Ferrans

Wenn Sie möchten, dass die Daten konsistent bestellt werden, ja - Sie müssen ORDER BY verwenden.

9
OMG Ponies

Ja. Es gibt keine "Standardreihenfolge" ohne ORDER BY, und es gibt keine Garantie, dass Sie die Daten in FIFO/LIFO oder in einer anderen Reihenfolge zurückerhalten.

Soweit die Entwickler "SELECT id, name FROM table" verwenden, sind sie entweder unfähig oder es ist ihnen egal, in welcher Reihenfolge etwas erscheint.

6
Ken White

Kein ernsthaftes RDBMS garantiert eine Bestellung es sei denn Sie geben explizit ORDER BY an.

Alles andere ist nur reines Glück oder anectodal - wenn Sie bestellen möchten, müssen Sie ORDER BY angeben - kein Weg, um das zu umgehen.

3
marc_s

Wenn Sie möchten, dass die Daten bestellt werden, ist die einzige Möglichkeit, irgendetwas zu garantieren (bei jedem größeren RDBMS-System, das mir bekannt ist, definitiv Sql Server und Oracle), die Verwendung einer ORDER BY-Klausel. FIFO hat absolut nichts damit zu tun, dass die Bestelldaten ohne eine ORDER BY-Klausel zurückgegeben werden, und es gibt kein Konzept einer DEFAULT-Sortierreihenfolge. Die sogenannte DEFAULT-Sortierreihenfolge ist im Grunde jedoch die Engine erhält die Daten, die buchstäblich in beliebiger Reihenfolge sein können, basierend auf Indizes, zwischengespeicherten Daten, gleichzeitiger Ausführung von Abfragen, Last auf dem Server usw. usw.

Dieser andere Stackoverflow-Thread deckt im Grunde das gleiche Konzept in Bezug auf SQL-Server ab. AlexK hat ein Repo gebloggt , um das Verhalten zu demonstrieren.

3
boydc7

In SQL habe ich meistens kein ORDER BY in SQL angegeben, da die Datensätze in einem Rastersteuerelement " clientseitig " angezeigt werden usw., wo die dynamische Sortierung unterstützt wird - in diesem Fall ist die Sortierung nach SQL unnötig , da sie ohnehin clientseitig geprüft wird. 

Dies geschieht auch auf der Clientseite, da möglicherweise dieselbe Abfrage verwendet wird, um die Daten an unterschiedlichen Stellen in unterschiedlicher Reihenfolge anzuzeigen.

Daher ist es nur empfehlenswert, wenn Sie eine ORDER BY eingeben

  • Die Reihenfolge der DatenISTwichtig; und
  • Die Sortierung ist auf DB-Ebene effizienter.

d.h. wenn der Front-End-Entwickler es ohnehin "umsortieren" wird, ist dies sinnlos, da es unwahrscheinlich ist, dass die Gesamtverarbeitungszeit gespart wird.

3
simo.37920

Sogar eine einfache Abfrage wie SELECT ... FROM table kann Daten in verschiedener Reihenfolge zurückgeben. Ich weiß, dass dies theoretisch wahr ist, ich weiß, dass dies in der Praxis stimmt, und ich habe viele Fälle gesehen, in denen sich die Reihenfolge zwischen aufeinanderfolgenden Ausführungen ändert, selbst wenn in der Tabelle keine Datenänderungen auftreten.

Ein typisches Beispiel für Auftragsänderungen zwischen Ausführungen ist, wenn die Abfrage mit einem parallelen Plan ausgeführt wird. Da parallele Operatoren Daten zurückgeben, während die zugrunde liegenden Threads sie erzeugen, variiert die Reihenfolge der Zeilen im Ergebnis zwischen den einzelnen Durchläufen. Diese Situation führt dazu, dass selbst die einfache SELECT-Anweisung in Ihrem Beispiel bei jeder Ausführung stark unterschiedliche Ergebnisse liefert.

3
Remus Rusanu

Möglicherweise kümmern sich die Autoren dieser SQL-Abfragen, die Sie lesen, nicht um die Reihenfolge der zurückgegebenen Daten. Am besten verwenden Sie es an Stellen, an denen Sie die Reihenfolge der Ergebnisse sicherstellen müssen!

1
Mike Atlas

Ich schreibe dies für den Fall, dass jemand dies gerne so verwenden möchte.

Nun, ich bekomme eine zufriedenstellende Standard-Sortierreihenfolge, beispielsweise für Log-Tabellen, mit Sortierung nach Index. Zum Beispiel bin ich normalerweise an den letzten Zeilen der Protokolltabelle (LIFO) interessiert, daher mache ich DateTime DESC als Reihenfolge. Ich habe auch aus Spaß versucht, Index in das andere Feld (Integer) neben Primärschlüssel einzufügen, und es hat funktioniert.

CREATE TABLE [dbo].[tableA]([DateTime] [datetime] NOT NULL,
CONSTRAINT [PK_tableA] 
PRIMARY KEY CLUSTERED ([DateTime] DESC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]

Oder in SSMS ...

 enter image description here

0
hoggar