我有两个我考虑使用的分页查询.
第一个是
SELECT * FROM ( SELECT rownum rnum, a.* from (
select * from members
) a WHERE rownum <= #paging.endRow# ) where rnum > #paging.startRow#
Run Code Online (Sandbox Code Playgroud)
第二是
SELECT * FROM ( SELECT rownum rnum, a.* from (
select * from members
) a ) WHERE rnum BETWEEN #paging.startRow# AND #paging.endRow#
Run Code Online (Sandbox Code Playgroud)
您如何看待哪个查询更快?
Ale*_*ssi 15
我现在实际上没有Oracle的可用性,但是对于分页的最佳SQL查询肯定是以下内容
select *
from (
select rownum as rn, a.*
from (
select *
from my_table
order by ....a_unique_criteria...
) a
)
where rownum <= :size
and rn > (:page-1)*:size
Run Code Online (Sandbox Code Playgroud)
http://www.oracle.com/technetwork/issue-archive/2006/06-sep/o56asktom-086197.html
要实现一致的分页,您应该使用唯一标准对行进行排序,这样可以避免为页面X加载已为页面Y加载的行(!= X).
看一下执行计划,例如1000行:
SELECT *
FROM (SELECT ROWNUM rnum
,a.*
FROM (SELECT *
FROM members) a
WHERE ROWNUM <= endrow#)
WHERE rnum > startrow#;
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1000 | 39000 | 3 (0)| 00:00:01 |
|* 1 | VIEW | | 1000 | 39000 | 3 (0)| 00:00:01 |
| 2 | COUNT | | | | | |
|* 3 | FILTER | | | | | |
| 4 | TABLE ACCESS FULL| MEMBERS | 1000 | 26000 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("RNUM">"STARTROW#")
3 - filter("MEMBERS"."ENDROW#">=ROWNUM)
Run Code Online (Sandbox Code Playgroud)
2.
SELECT *
FROM (SELECT ROWNUM rnum
,a.*
FROM (SELECT *
FROM members) a)
WHERE rnum BETWEEN startrow# AND endrow#;
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1000 | 39000 | 3 (0)| 00:00:01 |
|* 1 | VIEW | | 1000 | 39000 | 3 (0)| 00:00:01 |
| 2 | COUNT | | | | | |
| 3 | TABLE ACCESS FULL| MEMBERS | 1000 | 26000 | 3 (0)| 00:00:01 |
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("RNUM"<="ENDROW#" AND "RNUM">="STARTROW#")
Run Code Online (Sandbox Code Playgroud)
除此之外,我认为版本2 可能会稍快一些,因为它包含的步骤少了一步.但我不知道您的索引和数据分布,因此您可以自己获取这些执行计划并判断数据的情况.或者只是测试它.
| 归档时间: |
|
| 查看次数: |
26959 次 |
| 最近记录: |