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.