Oracle 分页查询性能

Ted*_*son 5 oracle

我是 Oracle 的新手,我注意到分页查询采用这种格式。

select * 
from ( select /*+ FIRST_ROWS(n) */ 
         a.*, ROWNUM rnum 
       from
         ( your_query_goes_here with filter and order by ) a 
       where
         ROWNUM <= :MAX_ROW_TO_FETCH ) 
where
  rnum  >= :MIN_ROW_TO_FETCH;
Run Code Online (Sandbox Code Playgroud)

http://www.oracle.com/technetwork/issue-archive/2006/06-sep/o56asktom-086197.html

为什么有一个额外的外部选择来拆分 min 和 max rownum where 子句?这是否同样具有性能和正确性?

select /*+ FIRST_ROWS(n) */
  *
from 
  ( your_query_goes_here with filter and order by )
where
  ROWNUM between :MIN_ROW_TO_FETCH and :MAX_ROW_TO_FETCH
Run Code Online (Sandbox Code Playgroud)

由于内部查询对值进行过滤和排序,ROWNUM 不应该已经正确了吗?

Jus*_*ave 3

不,第二个查询不起作用。:MIN_ROW_TO_FETCH如果大于 1,它将始终返回 0 行。

从概念上讲,如果您有类似的查询

select * /*+ FIRST_ROWS(n) */ 
  from ( your_query_goes_here with filter and order by )
  where ROWNUM between :MIN_ROW_TO_FETCH and :MAX_ROW_TO_FETCH
Run Code Online (Sandbox Code Playgroud)

其中:MIN_ROW_TO_FETCH11 和:MAX_ROW_TO_FETCH20,Oracle 将获取第一行,给它rownum1,然后丢弃它,因为它不满足谓词。然后它会从内部查询中获取第二行,给它一个rownum1(因为尚未成功返回任何行),然后丢弃它,因为它不满足谓词。这会重复进行,直到每一行都被获取、分配rownum为 1 并被丢弃。所以查询将返回 0 行。

额外的嵌套层可确保外部查询看到值介于 1 和 1 之间的rnum >= :MIN_ROW_TO_FETCH行,并且完整查询返回预期的行集。rnum:MAX_ROW_TO_FETCH

如果您使用 12.1 或更高版本,OFFSET ... FETCH也可以使用以下语法

SELECT *
  FROM table_name
 ORDER BY some_column
 OFFSET n ROWS
  FETCH NEXT m ROWS ONLY;
Run Code Online (Sandbox Code Playgroud)