ROW_NUMBER
é bastante ineficiente no Oracle
. Veja o artigo no meu blog para detalhes de desempenho:
- Oracle:ROW_NUMBER x ROWNUM
Para sua consulta específica, recomendo que você a substitua por
ROWNUM
e certifique-se de que o índice é usado: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 usará
COUNT STOPKEY
Além disso, certifique-se de
column
não é anulável ou adicione WHERE column IS NOT NULL
doença. Caso contrário, o índice não pode ser usado para recuperar todos os valores.
Observe que você não pode usar
ROWNUM BETWEEN :start and :end
sem uma subconsulta. ROWNUM
é sempre atribuído por último e verificado por último, é assim ROWNUM
's sempre vêm em ordem sem lacunas. Se você usar
ROWNUM BETWEEN 10 and 20
, a primeira linha que satisfizer todas as outras condições se tornará uma candidata para retorno, atribuída temporariamente com ROWNUM = 1
e falhar no teste de ROWNUM BETWEEN 10 AND 20
. Em seguida, a próxima linha será um candidato, atribuído com
ROWNUM = 1
e falhar, etc., então, finalmente, nenhuma linha será retornada. Isso deve ser contornado colocando
ROWNUM
's na subconsulta.