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.