Datenbankimplementierungen von ORDER BY in einer Unterabfrage

10

Ich verwende eine Anwendung (MapServer - http://mapserver.org/ ), die SQL-Anweisungen umschließt, sodass sich die ORDER BY-Anweisung in der inneren Abfrage befindet. Z.B

SELECT * FROM (
        SELECT ID, GEOM, Name
        FROM t
        ORDER BY Name
        ) as tbl

Die Anwendung verfügt über viele verschiedene Datenbanktreiber. Ich verwende hauptsächlich den MS SQL Server-Treiber und SQL Server 2008. Dies löst einen Fehler aus, wenn in einer Unterabfrage ein ORDER BY gefunden wird.

Aus den MS Docs (obwohl dies für SQL Server 2000 gilt, scheint es immer noch zu gelten):

Wenn Sie eine ORDER BY-Klausel in einer Ansicht, einer Inline-Funktion, einer abgeleiteten Tabelle oder einer Unterabfrage verwenden, wird keine geordnete Ausgabe garantiert. Stattdessen wird die ORDER BY-Klausel nur verwendet, um sicherzustellen, dass die vom Top-Operator generierte Ergebnismenge eine konsistente Zusammensetzung aufweist. Die ORDER BY-Klausel garantiert eine geordnete Ergebnismenge nur, wenn sie in der äußersten SELECT-Anweisung angegeben ist.

Der gleiche Abfragetyp, der in Postgres (9) und Oracle ausgeführt wird, gibt jedoch Ergebnisse zurück - mit der in der Unterabfrage definierten Reihenfolge. In Postgres zeigt der Abfrageplan, dass die Ergebnisse sortiert sind, und die Postgres-Versionshinweise enthalten den Artikel, der impliziert, dass Unterabfrageaufträge verwendet werden:

Vermeiden Sie das Sortieren, wenn die Unterabfrage ORDER BY mit der oberen Abfrage übereinstimmt

http://en.wikipedia.org/wiki/Order_by heißt es:

Obwohl einige Datenbanksysteme die Angabe einer ORDER BY-Klausel in Unterauswahlen oder Ansichtsdefinitionen zulassen, hat das Vorhandensein dort keine Auswirkung.

Jedoch aus meiner eigenen Überprüfung von Abfrageplänen:

  • SQL Server 2008 unterstützt ORDER BY in einer Unterabfrage nicht
  • Postgres 9 unterstützt ORDER BY in einer Unterabfrage
  • Oracle 10g unterstützt ORDER BY in einer Unterabfrage

Meine Frage, gibt es also Links, die offiziell bestätigen oder leugnen können, dass Postgres und Oracle das Sortieren in einer Unterabfrage nicht zulassen?

geographika
quelle
2
Nur weil Sie bestimmte Ergebnisse beobachten, sind diese nicht garantiert. Wenn Sie Konsistenz wünschen, geben Sie die Bestellung nach außen. Zeitraum.
Aaron Bertrand
Im Idealfall wird dies umgesetzt. Um zu diesem Stadium zu gelangen, müssen jedoch Änderungen an der Kernlogik und vielen Datenbanktreibern vorgenommen werden. Da dieses Problem seit vielen Jahren nicht mehr gemeldet wurde, scheint es, als würden einige Datenbankanbieter ORDER BY in Unterabfragen konsistent implementieren. Es wäre schön zu wissen, welche wenn möglich.
Geographika
2
@geographika Auch wenn einige DBMS dies bis jetzt konsequent tun, gibt es keine Garantie dafür, dass sie dies auch in Zukunft tun werden. Zum Beispiel würden MySQLs Verbesserungen des Optimierers in 5.6 (und MariaDB 5.3) das ORDER BYin der Unterabfrage als redundant identifizieren und nicht die unnötige Sortierung durchführen.
Ypercubeᵀᴹ

Antworten:

14

Sie müssen dafür sorgen, dass Ihre Anwendung das Innere nichtORDER BY in die Unterabfrage einfügt (möglicherweise besteht die Möglichkeit, überhaupt keine unnötige Unterabfrage zu verwenden). Wie Sie bereits festgestellt haben, wird diese Syntax in SQL Server ohne nicht unterstützt TOP. Und mit TOP, wenn Sie nicht einige Zeilen weglassen möchten, wird durch Verwenden TOP 100 PERCENTdie ORDER BYoptimierten ohnehin weggerendert.

Und in Oracle und PostGres, nur weil die Syntax unterstützt , bedeutet nicht , es befolgt wird. Und nur weil Sie beobachten, dass es in einem bestimmten Szenario befolgt wird, bedeutet dies nicht, dass es weiterhin befolgt wird, wenn neue Versionen herauskommen oder wenn Ihre Daten, Statistiken, die Abfrage selbst oder die Umgebung geringfügig geändert werden.

Ich kann Ihnen versichern, dass Sie ohne Zweifel , wenn Sie eine Garantie für die Bestellung wünschen , ORDER BYdie äußerste Anfrage stellen müssen. Dies sollte eine Doktrin sein, die Sie unabhängig von der verwendeten Plattform festhalten.

Sie fragen nach einem Link, der offiziell angibt, dass etwas nicht unterstützt wird. Dies ist so, als würden Sie in der Bedienungsanleitung Ihres Autos nach einer offiziellen Erklärung suchen, dass Ihr Auto nicht fliegen kann.

Aaron Bertrand
quelle
Vielen Dank. Ich denke, MSSQL hat den richtigen Ansatz, um einen Fehler auszulösen. Sowohl die Unterstützung als auch die Implementierung der Sortierung für innere Abfragen, wenn sie gegen ein SQL-Kernprinzip verstoßen, scheint ein Rezept für eine Katastrophe zu sein. Ich bin mir jedoch nicht sicher über die Auto-Analogie - Sie müssen hinzufügen, dass Sie im Handbuch danach suchen, während das Auto tatsächlich fliegt.
Geographika
-1

Ich gebe zu, dass dies schwierig ist, aber wenn Sie in einer Notlage sind, versuchen Sie, die oberste Anzahl von Zeilen in der Unterabfrage zurückzugeben. Die Rückgabe der oberen 100 Prozent funktioniert nicht, aber wenn Sie die Probleme lösen möchten, können Sie die Anzahl der Zeilen abfragen und diese als Variable an TOP übergeben. Ich habe dies an einer Datenbank getestet, die auf Kompatibilitätsstufe 80 eingestellt ist, daher denke ich, dass es mit SQL 2000 funktionieren sollte.

SELECT * FROM (
        SELECT TOP (100000) ID, GEOM, Name
        FROM t
        ORDER BY Name
        ) as tbl
DBNull
quelle
Ich habe dies ursprünglich versucht und es schien für kleine Datensätze gut zu sortieren. Als ich jedoch sehr große Datensätze erhielt, wurde die Sortierung in SQL Server 2008R2 wieder zufällig. Bezieht sich vielleicht auf Speicher- / Seitengrößen?
Geographika
Entschuldigung, es hat nicht geholfen. Die Auswahl der besten 100 Prozent führte auch dazu, dass die Sortierung auf zufällig zurückgesetzt wurde.
DBNull
Dies funktioniert nicht, wenn die Abfrage parallel verläuft, insbesondere wenn sie Namenicht eindeutig ist. Es funktioniert möglicherweise nicht seriell weiter, wenn das Optimierungsprogramm einen anderen Index mit einer anderen Reihenfolge der Schlüsselspalten auswählt.
Erik Darling