ROW_NUMBER jest dość nieefektywny w Oracle .
Zobacz artykuł na moim blogu, aby uzyskać szczegółowe informacje na temat wydajności:
- Oracle:ROW_NUMBER a ROWNUM
W przypadku konkretnego zapytania zalecamy zastąpienie go ciągiem ROWNUM i upewnij się, że indeks jest używany:
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
To zapytanie będzie używać COUNT STOPKEY
Upewnij się też, że column nie dopuszcza wartości null lub dodaj WHERE column IS NOT NULL stan.
W przeciwnym razie indeks nie może być użyty do pobrania wszystkich wartości.
Pamiętaj, że nie możesz użyć ROWNUM BETWEEN :start and :end bez podzapytania.
ROWNUM jest zawsze przypisywana jako ostatnia i sprawdzana jako ostatnia, czyli ROWNUM są zawsze uporządkowane bez przerw.
Jeśli używasz ROWNUM BETWEEN 10 and 20 , pierwszy wiersz spełniający wszystkie inne warunki stanie się kandydatem do zwrócenia, tymczasowo przypisany z ROWNUM = 1 i nie zalicz testu ROWNUM BETWEEN 10 AND 20 .
Wtedy następny wiersz będzie kandydatem, przypisanym przez ROWNUM = 1 i nie powiedzie się itp., więc ostatecznie żadne wiersze nie zostaną zwrócone.
Należy to obejść, umieszczając ROWNUM jest w podzapytaniu.