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.