ROW_NUMBER е доста неефективно в Oracle .
Вижте статията в моя блог за подробности за ефективността:
- Oracle:ROW_NUMBER срещу ROWNUM
За вашата конкретна заявка бих ви препоръчал да я замените с ROWNUM и се уверете, че се използва индексът:
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
Тази заявка ще използва COUNT STOPKEY
Също така се уверете, че сте column не може да бъде нула или добавете WHERE column IS NOT NULL състояние.
В противен случай индексът не може да се използва за извличане на всички стойности.
Имайте предвид, че не можете да използвате ROWNUM BETWEEN :start and :end без подзаявка.
ROWNUM винаги се присвоява последен и се проверява последен, така е ROWNUM Винаги се подреждат без пропуски.
Ако използвате ROWNUM BETWEEN 10 and 20 , първият ред, който отговаря на всички останали условия, ще стане кандидат за връщане, временно присвоен с ROWNUM = 1 и се провали на теста на ROWNUM BETWEEN 10 AND 20 .
След това следващият ред ще бъде кандидат, присвоен с ROWNUM = 1 и неуспешен и т.н., така че накрая няма да бъдат върнати никакви редове.
Това трябва да се заобиколи, като се постави ROWNUM е в подзаявката.