oracle中的分页显示

来源:互联网 发布:淘宝详情页页头设置 编辑:程序博客网 时间:2024/04/30 01:21
oracle中的分页显示一般我们在页面上实现分页显示的时候都是采用的oracle提供的一个 rownum 来控制每页显示的行数的,一般的,我们要显示结果集的前20行,可以用SQL表示为: select * from service where rownum< 21 ; 同样的,如果我们要显示从20行到40行的数据时可能就会写成: select * from service where rownum < 41 and rownum > 19; 如果做过这样尝试的人可能会知道,rownum是不能采用“>”符号的,这句SQL提交后不会报错,但是返回不出结果集,因为rownum并不是一个存储在物理上的,而是根据用户的查询结果集自动生成的一个编号,总是从1开始的,所以oracle会认为“ rownum > 一个数”是不存在的,也就没有了结果集。同样的,rownum只能采用<、<=进行筛选,而不能用>、>=、!= 和 between 的。理解了这些,我们再来讨论“显示从20行到40行的数据”这个问题,我们可以采用子查询来解决rownum不能采用>的问题。所以我们可以采用多种方法来避开这个限制: 1)select * from ( select rownum rn ,a.* from service a ) where rn < 41 and rn > 19; 2)select rownum rn ,a.* from service a where rownum < 41 minus select rownum rn ,a.* from service a where rownum < 20 3)select * from ( select rownum rn ,a.* from service a where rownum < 41 ) where rn > 19; 对于第一种方法,没有什么可解释的了,首先将整个表整个显示出来,并且加上rownum,(就好像建立一张临时表,在原表上增加rownum这个字段一样),然后再在这个结果集中进行筛选,选出20~40行的数据。这是最简单明了的写法,但也是最慢的方法,因为首先他会将service表中所有的数据都load到内存中,然后才根据rownum进行筛选。对于第二种方法,他是将最大值和最小值作为两个小于的条件,根据这两个条件产生两个结果集,也就是将最大值的结果集作为被减数,将最小值的结果集作为减数,【大结果集】- 【小结果集】的结果就是中间的那部分数据了。这要比第一种方法好了很多,至少他不会将service整个表的load到内存中。但是这个写法也是有弊端的,例如service中有1000条记录,我要查询第950~1000行的数据,这个时候这种写法就会首先将1000行数据load到数据库中生成最大值结果集,然后再load前950行数据生成最小结果集,再minus,这样算来,一共load了1950行的数据,就没有第一种方法快了。其实最好的方法是第三种写法,首先根据最大值的限制,在第一次load service的时候,就只拿到从1~最大值这些数据,然后生成一个带 rownum 的结果集,然后在外部的查询中将rownum小于最小值的数据剔掉。这样就尽可能少的load了数据,就算象之前那个例子,此写法也只load了1000行数据,与第一种写法的cost是相等的。
原创粉丝点击