ROW_NUMBER
er ret ineffektiv i Oracle
.
Se artiklen i min blog for detaljer om ydeevne:
- Oracle:ROW_NUMBER mod ROWNUM
Til din specifikke forespørgsel vil jeg anbefale dig at erstatte den med ROWNUM
og sørg for at indekset bruges:
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
Denne forespørgsel vil bruge COUNT STOPKEY
Sørg også enten for at column
er ikke nullbar, eller tilføj WHERE column IS NOT NULL
tilstand.
Ellers kan indekset ikke bruges til at hente alle værdier.
Bemærk, at du ikke kan bruge ROWNUM BETWEEN :start and :end
uden en underforespørgsel.
ROWNUM
er altid tildelt sidst og markeret sidst, på den måde ROWNUM
's kommer altid i orden uden huller.
Hvis du bruger ROWNUM BETWEEN 10 and 20
, vil den første række, der opfylder alle andre betingelser, blive en kandidat til returnering, midlertidigt tildelt ROWNUM = 1
og mislykkes testen af ROWNUM BETWEEN 10 AND 20
.
Så vil den næste række være en kandidat, tildelt ROWNUM = 1
og mislykkes osv., så endelig bliver der slet ingen rækker returneret.
Dette bør løses ved at indsætte ROWNUM
's i underforespørgslen.