Ich habe eine Oracle-Datenbank, die mit Millionen Datensätzen gefüllt ist. Ich versuche, eine SQL-Abfrage zu schreiben, die die ersten 'N' sortierten Datensätze (etwa 100 Datensätze) basierend auf bestimmten Bedingungen aus der Datenbank zurückgibt.
%Vor%Wählen Sie dann programmatisch die ersten N Datensätze aus.
Das Problem mit diesem Ansatz ist:
Meine Fragen sind:
Wenn Sie 100 zufällige Zeilen suchen und danach sortieren möchten, Lasses Lösung ist korrekt. Wenn ich denke, dass Sie die ersten 100 Zeilen nach Namen sortiert haben möchten, während Sie die anderen verworfen haben, würden Sie eine Abfrage wie diese erstellen:
%Vor%Der Optimierer wird verstehen, dass es sich um eine TOP-N-Abfrage handelt, und kann einen Index für NAME verwenden. Es muss nicht die gesamte Ergebnismenge sortieren, es beginnt einfach am Ende des Index und liest es rückwärts und stoppt nach 100 Zeilen.
Sie könnten Ihrer ursprünglichen Abfrage auch einen Hinweis hinzufügen, damit der Optimierer erkennt, dass Sie nur an den ersten Zeilen interessiert sind. Dies wird wahrscheinlich einen ähnlichen Zugriffspfad erzeugen:
%Vor% Bearbeiten: Das Hinzufügen von AND rownum <= 100
zur Abfrage funktioniert nicht, da in Oracle rownum vor Sortierung zugeordnet ist: Deshalb müssen Sie eine Unterabfrage verwenden. Ohne die Unterabfrage wählt Oracle 100 zufällige Zeilen und sortiert sie dann.
Dies zeigt, wie Sie die obersten N Zeilen je nach Ihrer Oracle-Version auswählen können.
Ab Oracle 9i sind RANK () und DENSE_RANK () Funktionen können verwendet werden Bestimmen Sie die TOP N Zeilen. Beispiele:
Holen Sie sich die Top 10 Mitarbeiter basierend auf ihr Gehalt
SELECT ename, sal FROM (SELECT ename, sal, RANK () ÜBER (ORDER BY sal DESC) sal_rank FROM emp) WO sal_rank & lt; = 10;
Wählen Sie die Mitarbeiter aus, die die Top 10 bilden Gehälter
SELECT ename, sal FROM (SELECT ename, sal, DENSE_RANK () ÜBER (BESTELLEN Mit sal DESC) sal_dense_rank FROM emp) WO sal_dense_rank & lt; = 10;
Der Unterschied zwischen den beiden ist hier
erklärtFügen Sie Folgendes hinzu:
%Vor%zu Ihrer WHERE-Klausel.
Das wird jedoch nicht tun, was Sie verlangen.
Wenn Sie 100 zufällige Zeilen auswählen, diese sortieren und dann zurückgeben möchten, müssen Sie zuerst eine Abfrage ohne ORDER BY formulieren, dann auf 100 Zeilen begrenzen, dann daraus auswählen und sortieren.
Dieses könnte funktionieren, aber leider habe ich keinen Oracle-Server zum Testen zur Verfügung:
%Vor%Aber beachte den "zufälligen" Teil dort, du sagst: "Gib mir 100 Reihen mit GRÖSSE & gt; 2000, mir ist egal, welche 100".
Willst du das wirklich?
Und nein, Sie werden nicht wirklich ein zufälliges Ergebnis erhalten, in dem Sinne, dass es sich bei jeder Abfrage des Servers ändert, aber Sie sind dem Abfrageoptimierer ausgeliefert. Wenn sich die Datenlade- und Indexstatistik für diese Tabelle im Laufe der Zeit ändert, erhalten Sie möglicherweise andere Daten als bei der vorherigen Abfrage.
Ihr Problem besteht darin, dass die Sortierung bei jeder Ausführung der Abfrage durchgeführt wird. Sie können die Sortieroperation mit einem Index eliminieren - der Optimierer kann einen Index verwenden, um eine Sortieroperation zu eliminieren - wenn die sortierte Spalte mit NOT NULL deklariert ist.
(Wenn die Spalte nullfähig ist, ist es immer noch möglich, entweder (a) ein NOT NULL-Prädikat zur Abfrage hinzuzufügen oder (b) einen funktionsbasierten Index hinzuzufügen und die ORDER BY-Klausel entsprechend zu ändern).
Tags und Links sql oracle sorting sql-order-by