In welcher Reihenfolge werden die Zeilen ohne ORDER BY-Klausel abgerufen?

11

Ein Programmierer testet und vergleicht dieselbe Anwendung, die dieselbe Datenbankstruktur und dieselben Daten verwendet, nur in zwei separaten Datenbanken, eine mit Oracle 8 und eine mit Oracle 9.

Die App führt eine Abfrage ohne ORDER BY Klausel aus.

Er behauptet, dass die ORDER-BY-less-Abfrage die Zeilen in beiden Datenbanken in derselben Reihenfolge zurückgeben sollte.

Ich sage ihm, dass es keine Garantie für dieselbe Zeilenreihenfolge gibt, es sei denn, Sie geben ausdrücklich eine ORDER BY-Klausel an.

Die Datenbank hat dieselben Indizes und Schlüssel. Der EXPLAIN-Plan zeigt jedoch, dass die Engine in einer der Datenbanken den Schlüssel einer der verknüpften Tabellen verwendet, während sie in der anderen Datenbank den Schlüssel einer anderen verwendet.

Er unterstellt, dass die beiden DB-Umgebungen nicht gleich sind, weil sie unterschiedliche Statistiken, unterschiedliche rdbms-Engines usw. haben, aber nicht, weil ich nicht jeden Index der ursprünglichen Datenbank replizieren konnte.

Ich sage ihm, dass er explizit eine ORDER BYKlausel vorlegen muss, wenn die Reihenfolge wirklich so wichtig ist.

Die Frage

So kann ich ihn besser erklären:

In welcher Reihenfolge ruft eine Abfrage Zeilen ab, wenn Sie keine ORDER BY-Klausel explizit angeben, und warum gibt diese Abfrage die Zeilen nicht in derselben Reihenfolge zurück?

Tulains Córdova
quelle
3
Es ist undefiniert. Ich glaube nicht, dass die SQL-Spezifikation die spezifische Reihenfolge angibt, in der Datensätze zurückgegeben werden sollen, daher wird sie implementierungsabhängig sein.
Robert Harvey
1
@ RobertHarvey Genau deshalb sage ich es ihm. In der Tat: Relationale Tabellen dürfen per Definition keine bestimmte Reihenfolge haben.
Tulains Córdova
1
Es kann sogar bei genau derselben Softwareversion sinnvoll sein, einen anderen Index zu verwenden, da dieser möglicherweise selektiver ist, basierend auf den Indexstatistiken, die er für die genauen Daten in dieser Datenbank gesammelt hat. Sie können sich also wirklich nicht auf die Bestellung verlassen, wenn Sie sie nicht angeben.
Psr
Sie können realistisch erwarten, dass die erste Abfrage nach nicht indizierter Spalte der Reihenfolge "Einfügezeit" folgt. durch indizierte "Aktualisierungszeit". Aufeinanderfolgende Anfragen können wahrscheinlich durch zwischengespeicherte Ergebnisse "verdorben" und daher ziemlich zufällig sein. Trotzdem hängt es nie davon ab - es kann sich von Version zu Version ändern, durch Parameter, durch Aktualisierungsvorgänge und durch schlechtes Wetter bei Vollmond. "Undefiniert" ist die richtige Antwort, und alles andere ist bestenfalls eine fundierte Vermutung.
SF.
1
Von RDMBS-es zurückgegebene Ergebnismengen sind genau das: Mengen , die per Definition keine bestimmte Reihenfolge haben. Das RDBMS kann sie also in beliebiger Reihenfolge zurückgeben und die Reihenfolge bei der nächsten Abfrageausführung erneut ändern. Sich auf eine bestimmte Bestellung ohne eine ORDER BY-Klausel zu verlassen, wäre ein Fehler. Ich versuche immer, dies meinen Mitarbeitern zu erklären, aber ich bin nur die halbe Zeit erfolgreich: D.
Radu Murzea

Antworten:

25

Aus Wikipedia :

Die ORDER BY-Klausel gibt an, welche Spalten zum Sortieren der resultierenden Daten verwendet werden und in welche Richtung sie sortiert werden sollen (Optionen sind aufsteigend oder absteigend). Ohne eine ORDER BY-Klausel ist die Reihenfolge der von einer SQL-Abfrage zurückgegebenen Zeilen undefiniert.

Es ist also undefiniert.

Die SQL-Spezifikation gibt nicht die spezifische Reihenfolge an, in der Datensätze zurückgegeben werden sollen, daher ist sie implementierungsabhängig.

Ohne Indizes in der Tabelle wäre die sinnvolle Reihenfolge die Reihenfolge, in der die Datensätze eingefügt wurden. Wenn ein Primärschlüssel definiert ist, ist die sinnvolle Reihenfolge die Reihenfolge des Primärschlüssels. Da für die ANSI-Spezifikation jedoch keine bestimmte Bestellung erforderlich ist, ist dies Sache des Anbieters, und ihre Sensibilität kann von Ihrer oder meiner abweichen.

Da die Bestellung nicht in der Spezifikation angegeben ist, ist es nicht ratsam, sich auf das Verhalten der Implementierung eines bestimmten Anbieters zu verlassen, da diese von Anbieter zu Anbieter unterschiedlich sein kann und der Anbieter die Bestellung jederzeit ohne Vorwarnung ändern kann.

Wie Sie sagten, fügen Sie einfach die ORDER BYKlausel hinzu, wenn die Reihenfolge wichtig ist.

Robert Harvey
quelle
Die Abfrage enthält mehrere verknüpfte Tabellen. Eine DB-Engine sortiert die Ergebnismenge nach einem Kriterium, und die andere DB verwendet andere Kriterien. Wenn eine ORDER BY-Klausel angegeben wird, geben beide Abfragen die Zeilen in der angegebenen Reihenfolge zurück.
Tulains Córdova
+1 AFAICR Die Reihenfolge kann sogar jedes Mal variieren, wenn Sie eine bestimmte Abfrage für eine bestimmte Datenbankinstanz ausführen.
MarkJ
2
Ich würde sagen, dass ohne eine ORDER BY-Klausel die einzig sinnvolle Ergebnisreihenfolge das ist, was den geringsten Overhead verursacht. Bei einfachen DB-Speicher-Engines und Abfragen ist dies häufig die Einfügereihenfolge (und bei generierten Primärschlüsseln die gleiche wie bei der Primärschlüsselreihenfolge). Aber sobald Sie Hash dabei haben, würde ich erwarten, dass die Reihenfolge im Wesentlichen zufällig ist.
Michael Borgwardt
2

Der Hinweis, dass die Spezifikation nicht angibt, in welcher Reihenfolge die Daten eingehen, hat nicht funktioniert. Wahrscheinlich, weil er weiß, dass sich die Daten irgendwo auf einer Festplatte oder im Speicher befinden und dies daher als Auftrag haben. Fragen Sie ihn nach der Reihenfolge der berechneten Daten aus mehreren Tabellen. Das heißt, Sie erstellen ein Beispiel, in dem Sie 4 Tabellen verbinden, 2 davon berechnen und nur den berechneten Wert zurückgeben.

Die Engine gibt die Daten in der Reihenfolge zurück, in der sie gefunden wurden (ohne eine Reihenfolge von). Wie sie gefunden werden, hängt jedoch von Faktoren ab, die sich ändern können - Indizes, Statistiken, Caches. Im Allgemeinen werden die Daten in einer konsistenten Reihenfolge angezeigt. Wenn Sie jedoch von der Reihenfolge abhängig sind, müssen Sie danach fragen.

jmoreno
quelle