ROW_NUMBER
ist ziemlich ineffizient in Oracle
.
Einzelheiten zur Leistung finden Sie im Artikel in meinem Blog:
- Oracle:ROW_NUMBER vs. ROWNUM
Für Ihre spezifische Abfrage würde ich Ihnen empfehlen, es durch ROWNUM
zu ersetzen und stellen Sie sicher, dass der Index verwendet wird:
SELECT *
FROM (
SELECT /*+ INDEX_ASC(t index_on_column) NOPARALLEL_INDEX(t index_on_column) */
t.*, ROWNUM AS rn
FROM table t
ORDER BY
column
)
WHERE rn >= :start
AND rownum <= :end - :start + 1
Diese Abfrage verwendet COUNT STOPKEY
Stellen Sie außerdem sicher, dass Sie column
nicht nullfähig ist, oder fügen Sie WHERE column IS NOT NULL
hinzu Zustand.
Andernfalls kann der Index nicht verwendet werden, um alle Werte abzurufen.
Beachten Sie, dass Sie ROWNUM BETWEEN :start and :end
nicht verwenden können ohne Unterabfrage.
ROWNUM
wird immer zuletzt zugewiesen und zuletzt geprüft, also ROWNUM
's immer in Ordnung ohne Lücken kommen.
Wenn Sie ROWNUM BETWEEN 10 and 20
verwenden , wird die erste Zeile, die alle anderen Bedingungen erfüllt, ein Kandidat für die Rückgabe, vorübergehend zugewiesen mit ROWNUM = 1
und den Test von ROWNUM BETWEEN 10 AND 20
nicht bestehen .
Dann ist die nächste Zeile ein Kandidat, zugewiesen mit ROWNUM = 1
und fehlschlagen usw., so dass schließlich überhaupt keine Zeilen zurückgegeben werden.
Dies sollte durch Setzen von ROWNUM
umgangen werden 's in die Unterabfrage.