ROW_NUMBER
is vrij inefficiënt in Oracle
.
Zie het artikel in mijn blog voor prestatiedetails:
- Oracle:ROW_NUMBER versus ROWNUM
Voor uw specifieke vraag raad ik u aan deze te vervangen door ROWNUM
en zorg ervoor dat de index wordt gebruikt:
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
Deze zoekopdracht gebruikt COUNT STOPKEY
Zorg er ook voor dat u column
is niet nullable, of voeg WHERE column IS NOT NULL
. toe staat.
Anders kan de index niet worden gebruikt om alle waarden op te halen.
Merk op dat u ROWNUM BETWEEN :start and :end
. niet kunt gebruiken zonder een subquery.
ROWNUM
wordt altijd als laatste toegewezen en als laatste gecontroleerd, dus ROWNUM
's komen altijd in orde zonder gaten.
Als u ROWNUM BETWEEN 10 and 20
. gebruikt , de eerste rij die aan alle andere voorwaarden voldoet, wordt een kandidaat voor terugkeer, tijdelijk toegewezen met ROWNUM = 1
en niet slagen voor de test van ROWNUM BETWEEN 10 AND 20
.
Dan is de volgende rij een kandidaat, toegewezen met ROWNUM = 1
en falen, enz., dus uiteindelijk worden er helemaal geen rijen geretourneerd.
Dit moet worden omzeild door ROWNUM
. in te voeren zit in de subquery.