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.