公司Oracle分页模板探究

在第一家公司实习时曾需要解决这样一个问题:从百万数量级的日志中分页查询按时间排序的日志,当时实现的结果是查询非常非常慢,而且越是后面的页就越慢。现在想来,当时忽略了两个问题:

    ①排序问题,我当时强烈主张排序应该去掉,通过在时间字段上增加了索引,已经可以保证查询结果按时间顺序排列,没有必要加;另一方面,对百万数量级的日志进行排序,消耗可想而知。

    ②分页查询方法问题,当时采用的是rownum的分页方法,如下:

    select * from

        (select *, rn from tableName where rownum<#endRow#)

    where rn>#startRow#

    假设页号为page、页大小为pageSize,查询第page页会在内层子查询中返回page*pageSize条记录,所以当页数越大时,子查询要返回的记录数就越多,当面对上述百万数量级的查询时,子查询的时间消耗和内存消耗是相当难以接受的。

 

所以出了排序的问题以外,使用rowid来进行分页查询在大数据量的情形下会获得较好的效果,下面先介绍使用方法:

    select *

        from (

            select rid

                 from (

                     select rid, rownum as rn from(

                          select l1.rowid as rid from table1 l1

                      )where rownum<=page*pageSize

            )where rn>=(page-1)*pageSize+1

         )t1,table1 t2 where t1.rid=t2.rowid  

内层子查询只查询返回rowid,最后再外层通过rowid获得相应的记录,因此查询在大数据量的分页查询中,第二种方法的性能会明显高于第一种。

关于rowid和rownum伪列,rownum和数据的组织方式相关,它不能唯一标识记录,如果你没有定义主键或能唯一标识记录的字段的话,唯一标识记录的是rowid,插入一条记录后就为有个唯一的rowid来标识,且rowid不会再改变。但是如果你的表改变了表空间的话,rowid也可能会改变。rowidrownum 虽都被称为伪列,但它们的存在方式是不一样的,rowid 可以说是物理存在的,表示记录在表空间中的唯一位置ID,在DB中是唯一的。只要记录没被搬动过,rowid是不变的。rowid可以通过base64解码函数解码获得记录的存储信息:

SQL> select rowid ,
  2          B64.Base64_2Dec(substr(rowid,1,6)) object_no ,
  3          B64.Base64_2Dec(substr(rowid,7,3)) rel_file_id,
  4          B64.Base64_2Dec(substr(rowid,10,6)) block_no,
  5          B64.Base64_2Dec(substr(rowid,16,3)) row_no
  6  from emp a
  7  where rownum <= 5
  8  /
reference:http://jametong.itpub.net/post/5042/25513

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值