ROW_NUMBER
es bastante ineficiente en Oracle
.
Consulte el artículo de mi blog para obtener detalles sobre el rendimiento:
- Oracle:ROW_NUMBER frente a ROWNUM
Para su consulta específica, le recomiendo que la reemplace con ROWNUM
y asegúrese de que se utiliza el índice:
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
Esta consulta utilizará COUNT STOPKEY
También asegúrese de column
no admite valores NULL, o agregue WHERE column IS NOT NULL
condición.
De lo contrario, el índice no se puede utilizar para recuperar todos los valores.
Tenga en cuenta que no puede usar ROWNUM BETWEEN :start and :end
sin una subconsulta.
ROWNUM
siempre se asigna en último lugar y se comprueba en último lugar, así es ROWNUM
siempre viene en orden sin espacios.
Si usa ROWNUM BETWEEN 10 and 20
, la primera fila que satisfaga todas las demás condiciones se convertirá en candidata para regresar, asignada temporalmente con ROWNUM = 1
y falla la prueba de ROWNUM BETWEEN 10 AND 20
.
Luego, la siguiente fila será un candidato, asignado con ROWNUM = 1
y falla, etc., por lo que, finalmente, no se devolverá ninguna fila.
Esto debería solucionarse poniendo ROWNUM
's en la subconsulta.