ROW_NUMBER
est assez inefficace dans Oracle
.
Voir l'article de mon blog pour plus de détails sur les performances :
- Oracle :ROW_NUMBER contre ROWNUM
Pour votre requête spécifique, je vous recommande de le remplacer par ROWNUM
et assurez-vous que l'index est utilisé :
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
Cette requête utilisera COUNT STOPKEY
Assurez-vous également que vous column
n'accepte pas la valeur NULL ou ajoutez WHERE column IS NOT NULL
état.
Sinon, l'index ne peut pas être utilisé pour récupérer toutes les valeurs.
Notez que vous ne pouvez pas utiliser ROWNUM BETWEEN :start and :end
sans sous-requête.
ROWNUM
est toujours attribué en dernier et vérifié en dernier, c'est-à-dire ROWNUM
sont toujours dans l'ordre sans lacunes.
Si vous utilisez ROWNUM BETWEEN 10 and 20
, la première ligne qui satisfait toutes les autres conditions deviendra un candidat pour le retour, temporairement affecté avec ROWNUM = 1
et échouer au test de ROWNUM BETWEEN 10 AND 20
.
Ensuite, la ligne suivante sera un candidat, attribué avec ROWNUM = 1
et échouer, etc., donc, finalement, aucune ligne ne sera renvoyée du tout.
Cela devrait être contourné en mettant ROWNUM
est dans la sous-requête.