Oracle 也来谈谈分页

  做开发的,或者一些新手对分页应该不模糊,也是平常使用的最多的一个功能。现在比较一些主要的分页方式:

1.使用rownum的 分页

select ename,deptno from (
 select ename,deptno,rn
 from (
 select ename,deptno,rownum rn
 from emp order by deptno
 )
 where rownum between 12 and 24 
)

这种分页一看就比较差,使用了between and 这种比较差的谓词,还有一个缺点就是

在层层嵌套的过程,都需要把 业务需要的数据列的投影取出来,这也是影响效率的,还好

oracle 是行式数据库,这一点影响还不大。

  

2.

select ename,deptno from
(select ename,deptno,rn
 from
 (select ename,deptno,rownum rn
 from emp
 where rownum<12
 )where  rn>5
)

这种分页 是大家使用的最多的一种分页方式,没有什么好说的。

3.

select /*+ first_row()*/ ename,deptno from
(select ename,deptno,rn
 from
 (select ename,deptno,rownum rn
 from emp
 where rownum<12
 )where  rn>5
)

这种就比较上境界了,如果你的系统是oltp系统的话,系统默认的CBO是all_row() 的方式,而分页是

特别不适合这种方式的,加上这个hint的话就完美了,兼顾了两者的优劣势。

4.根据 RowId 来分页

select
where ename,deptno
from emp
where rowid in
(
 select rowid from
 (
 select rowid,rownum,rowid,deptno
 from 
 (select deptno,rowid from
 emp order by deptno
 ) where rownum <12
 ) where rownum >5
    )
)

这种分页 解决了我们在1,2中遇到的问题,也就是直到最后一层才进行数据的垂直映射。效率就提高了,但是又有一个问题,在排序时是要取出排序列的, deptno 不是主键,是外键,有外键索引,而且是数字,问题不大。但是如果是时间等不是索引的话,

的话在上面查找排序,也是一样效率不好的。

5. 使用分析函数来做分页

select * from (
select * ,row_number() over (order by deptno)
 rk from emp
) where rk<16 and rk>5
)

这种分页最简单,同时也是效率最低的,

原文地址:https://www.cnblogs.com/jerryxing/p/2650333.html