ROW_NUMBER
的效率很低Oracle
。
对于您的特定查询,建议您将其替换为ROWNUM
并确保使用索引:
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
该查询将使用 COUNT STOPKEY
另外,请确保您column
不可为空,或添加WHERE column IS NOT NULL
条件。
否则,索引不能用于检索所有值。
请注意,ROWNUM BETWEEN :start and :end
没有子查询就无法使用。
ROWNUM
总是最后被分配并最后检查,这就是方法ROWNUM
总是无间隙地排列。
如果您使用ROWNUM BETWEEN 10 and 20
,则满足所有其他条件的第一行将成为返回的候选项,并被临时分配ROWNUM = 1
并通过的测试失败ROWNUM BETWEEN 10 AND 20
。
然后,下一行将是候选行,并分配有ROWNUM = 1
和失败等,因此,最后,将根本不返回任何行。