ROW_NUMBER è abbastanza inefficiente in Oracle .
Vedi l'articolo nel mio blog per i dettagli sulle prestazioni:
- Oracle:ROW_NUMBER vs ROWNUM
Per la tua richiesta specifica, ti consiglio di sostituirlo con ROWNUM e assicurati che l'indice sia utilizzato:
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
Questa query utilizzerà COUNT STOPKEY
Assicurati anche di column non è nullable o aggiungi WHERE column IS NOT NULL condizione.
In caso contrario, l'indice non può essere utilizzato per recuperare tutti i valori.
Nota che non puoi usare ROWNUM BETWEEN :start and :end senza una sottoquery.
ROWNUM è sempre assegnato per ultimo e controllato per ultimo, così è ROWNUM arriva sempre in ordine, senza interruzioni.
Se utilizzi ROWNUM BETWEEN 10 and 20 , la prima riga che soddisfa tutte le altre condizioni diventerà candidata alla restituzione, assegnata temporaneamente con ROWNUM = 1 e fallisci il test di ROWNUM BETWEEN 10 AND 20 .
Quindi la riga successiva sarà un candidato, assegnato con ROWNUM = 1 e fail, ecc., quindi, alla fine, non verrà restituita alcuna riga.
Questo dovrebbe essere risolto inserendo ROWNUM è nella sottoquery.