最近在找oracle的分页存储过程,在google上一搜,基本就是这么两种,都是基于rownum的:1.采用row_number解析函数
SELECT xx.* FROM(
SELECT t.*,row_number() over(ORDER BY id)AS num
FROM t_order t
)xx
WHERE num BETWEEN 5 AND 15;
--返回第5-15行数据2.采用rownum关键字(三层嵌套)
SELECT * FROM(
  SELECT A.*,ROWNUM  num FROM 
  (SELECT * FROM t_order ORDER BY id) A
  WHERE
  ROWNUM<=15)
WHERE num>=5;--返回第5-15行数据
我和经理讨论了一下,发现这两种方法都有着致命的缺点:
a.最内层查询都把所有列先查出来了(t.*、A.*)。若有好几十个列,这样先查出来效率岂不是很低?(虽然早晚都要把需要的列都查出来,但是待会在外层还要再查一次,内层先查等于做了重复的工作!)
b.最内层查询把所有行都查出来了,比如有100w条数据,那先查出来这100w条,然后在外层查询在用rownum分页,这样做效率太低了啊!我的想法是,在最内层查询就用rownum生成一个序号列,再查一个主键ID出来,这样内存查询出来的表temp只有两列(这样是不是效率能高些?)。到了外层查询用表temp的ID和t_order的ID内连查询,再用内层查询生成的ROWNUM分页。
SELECT temp.* FROM (
SELECT t_order.id, row_number() over(ORDER BY id)AS num
FROM t_order
) temp 
inner join t_order on temp.id = t_order.id 
WHERE num BETWEEN 5 AND 15;请高手赐教

解决方案 »

  1.   

    内层查主键(主键默认建索引的),外层查需要的列。需要的字段名加入select后面,千万不要用select *,用select * 会有额外开销的。
    推荐用第一种方式来做。
      

  2.   

    做法就是这么个做法,只是提高下效率就可以了:1、在你的表上建立适当的索引
    2、使用绑定变量的方式,执行查询语句,这样能够使得oracle重复利用 第一次的sql解析结果,不用重复的解析新的sql语句,可以提高些效率。个人认为,主要就上面这两种方法,如果后来者有什么良策请留言交流。