您好,欢迎访问一九零五行业门户网

Oracle常见SQL分页实现方案介绍

在oracle中,用sql来实现分页有很多种实现方式,但有些语句可能并不是很通用,只能用在一些特殊场景之中; 以下介绍三种比较通用的实现方案;在以下各种实现中, rownum 是一个最核心的关键词,在查询时他是一个虚拟的列,取值为1到记录总数的序号; 首先来
在oracle中,用sql来实现分页有很多种实现方式,但有些语句可能并不是很通用,只能用在一些特殊场景之中;
以下介绍三种比较通用的实现方案;在以下各种实现中,rownum是一个最核心的关键词,在查询时他是一个虚拟的列,取值为1到记录总数的序号;
首先来介绍我们工作中最常使用的一种实现方式:
select *  from (select row_.*, rownum rownum_          from (select *                  from table1                 where table1_id = xx                 order by gmt_create desc) row_         where rownum = 20) where rownum_ >= 10;其中最内层的查询select为不进行翻页的原始查询语句,可以用自己的任意select sql替换;rownum = 10控制分页查询的每页的范围。
分页的目的就是控制输出结果集大小,将结果尽快的返回;上面的sql语句在大多数情况拥有较高的效率,主要体现在where rownum
上面例子中展示的在查询的第二层通过rownum
select *  from (select a.*, rownum rn          from (select *                  from table1                 where table1_id = xx                 order by gmt_create desc) a) where rn between 10 and 20;由于oracle可以将外层的查询条件推到内层查询中,以提高内层查询的执行效率,但不能跨越多层。
对于第一个查询语句,第二层的查询条件where rownum 而第二个查询语句,由于查询条件between 10 and 20是存在于查询的第三层,而oracle无法将第三层的查询条件推到最内层(即使推到最内层也没有意义,因为最内层查询不知道rn代表什么)。因此,对于第二个查询语句,oracle最内层返回给中间层的是所有满足条件的数据,而中间层返回给最外层的也是所有数据。数据的过滤在最外层完成,显然这个效率要比第一个查询低得多。
以上两种方案完全是通过rownum来完成,下面一种则采用rowid和rownum相结合的方式,sql语句如下:
select *  from (select rid          from (select r.rid, rownum linenum                  from (select rowid rid                          from table1                         where table1_id = xx                         order by gmt_create desc) r                 where rownum = 20)         where linenum >= 10) t1,       table1 t2 where t1.rid = t2.rowid;从语句上看,共有4层select嵌套查询,最内层为可替换的不分页原始sql语句,但是他查询的字段只有rowid,而没有任何待查询的实际表字段,具体查询实际字段值是在最外层实现的;
这种方式的原理大致为:首先通过rownum查询到分页之后的10条实际返回记录的rowid,最后通过rowid将最终返回字段值查询出来并返回;
和前面两种实现方式相比,该sql的实现方式更加繁琐,通用性也不是非常好,因为要将原始的查询语句分成两部分(查询字段在最外层,表及其查询条件在最内层);
但这种实现在特定场景下还是有优势的:比如我们经常要翻页到很后面,比如10000条记录中我们经常需要查9000-9100及其以后的数据;此时该方案效率可能要比前面的高;
因为前面的方案中是通过rownum
从不断向后翻页这个角度来看,第一种实现方案的成本会越来越高,基本上是线性增长,而第三种方案的成本则不会像前者那样快速,他的增长只体现在通过查询条件读取rowid的部分;
当然,除了以上提了这些方案,我们还可以用以下的sql来实现:
select *  from table1 where table1_id not in  (select table1_id from table1 where rownum = 10) and rownum = 10;
select *  from table1 where rownum = 20minusselect * from table1 where rownum = 10;………………
注意:当rownum作为查询条件时,他是在order by之前执行,所以要特别小心;
比如我们想查询table1中按table1_id倒序排列的前10条记录不能用如下的sql来完成:
select * from table1 where rownum = 10 order by table1_id desc;
其它类似信息

推荐信息