ROW_NUMBER je v Oracle docela neefektivní .
Podrobnosti o výkonu najdete v článku na mém blogu:
- Oracle:ROW_NUMBER vs. ROWNUM
Pro váš konkrétní dotaz bych vám doporučil nahradit jej výrazem ROWNUM a ujistěte se, že je použit index:
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
Tento dotaz bude používat COUNT STOPKEY
Také se ujistěte, že column nemá hodnotu null, nebo přidejte WHERE column IS NOT NULL podmínka.
Jinak nelze index použít k načtení všech hodnot.
Pamatujte, že nemůžete použít ROWNUM BETWEEN :start and :end bez dílčího dotazu.
ROWNUM je vždy přiřazen jako poslední a zkontrolován jako poslední, tedy ROWNUM 's vždy přišel v pořádku bez mezer.
Pokud používáte ROWNUM BETWEEN 10 and 20 , první řádek, který splňuje všechny ostatní podmínky, se stane kandidátem na vrácení, dočasně přiřazený s ROWNUM = 1 a neprojde testem ROWNUM BETWEEN 10 AND 20 .
Potom bude další řádek kandidát, kterému bude přiřazeno ROWNUM = 1 a fail atd., takže nakonec nebudou vráceny vůbec žádné řádky.
To by mělo být vyřešeno vložením ROWNUM 's do dílčího dotazu.