Wie werden die ersten 'N' Datensätze aus einer Datenbank mit Millionen Datensätzen ausgewählt?

8

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:

  • Die Abfrage führt zu einer halben Million Datensätze und "ORDER BY NAME" verursacht alle Datensätze, die in absteigender Reihenfolge nach NAME sortiert werden. Diese Sortierung benötigt viel Zeit. (fast 30-40 Sekunden. Wenn ich ORDER BY weglasse, dauert es nur 1 Sekunde).
  • Nach der Art, die mich interessiert nur erste N (100) Datensätze. Daher ist das Sortieren kompletter Datensätze nicht sinnvoll.

Meine Fragen sind:

  1. Ist es möglich, das 'N' einzugeben? sich selbst abfragen? (so dass die Sortierung nur für N Datensätze gilt und die Abfrage schneller wird).
  2. Besserer Weg in SQL, um die zu sortierende Abfrage zu verbessern nur N Elemente und zurück in schnell Zeit.
aJ. 11.09.2009, 09:53
quelle

5 Antworten

19

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.

    
Vincent Malgrat 11.09.2009, 10:07
quelle
5

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ärt     
IanH 11.09.2009 10:18
quelle
4

Fü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.

    
quelle
0

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).

    
Jeffrey Kemp 14.09.2009 13:45
quelle
0

Diese Aufgabe kann nur in Oracle 12c mit FETCH clause ausgeführt werden. Sie können hier sehen Beispiele und zusätzliche Referenzlinks zu diesem Thema.

    
Muntasir 27.12.2015 10:37
quelle

Tags und Links