Oracle数据库中分页查询中排序及效率问题

本文介绍了两种Oracle数据库分页查询的方法,并对比了它们的执行效率。通过对查询语句的优化,实现了更高效的分页效果。

原始未分页查询Sql代码如下:

select
 ROWNUM
 rn,
 t
.
id ID,
 o.
name
 YYB,
u.
name
 XM,
 t
.
MC from
 tZDYSX  
t , tuser u, lborganization o where t . cjr= u. id and u. orgid= o. orgcode and t . gx = 1
order by ID

结果如下:

RNIDYYBXMMC
349某证券总部管理员测试
496某证券总部管理员持有上港10000股以上
5102某证券总部管理员十年规划
14105某证券总部管理员开发渠道为上海
11106某证券总部管理员万科A
12107某证券总部管理员11
13108某证券总部管理员今天过生日的客户
2109某证券总部管理员客户状态正常
6110某证券总部管理员无交易
7111某证券总部管理员OA
8112某证券总部管理员幸运客户
9113某证券总部管理员风险型
10114某证券总部管理员tst
22115白沙网上交易安昌彪安客户正常
1118某证券总部管理员213
18119某证券总部管理员客户号包含1008
17120某证券总部管理员aaa
19123某证券总部管理员ssssssss
20124某证券总部管理员www
21126某证券总部管理员123123
15127某证券总部管理员1212
16128某证券总部管理员aaaaaa


22 rows selected 最初我使用如下Sql代码查询:

select
 *
 from
 (
select
 ROWNUM
 rn,
 t
.
id ID,
 o.
name
 YYB,
u.
name
 XM,
 t
.
MC    from
 tZDYSX t
,
tuser u,
lborganization o where
 t
.
cjr=
u.
id and
 u.
orgid=
o.
orgcode and
    t
.
gx =
 1 order
 by
 t
.
ID )
Where
 rn>
10 and
 rn<
=
20;

这种方法能成功分页,结果如下:

RNIDYYBXMMC
14105某证券总部管理员开发渠道为上海
11106某证券总部管理员万科A
12107某证券总部管理员11
13108某证券总部管理员今天过生日的客户
18119某证券总部管理员客户号包含1008
17120某证券总部管理员aaa
19123某证券总部管理员ssssssss
20124某证券总部管理员www
15127某证券总部管理员1212
16128某证券总部管理员aaaaaa


10 rows selected

从结果看来,有个问题:此语句Sql代码
order by CJSJ DESC  被执行,但是是在分后的第11到20条记录的结果集中再进行排序,而不是先排序后分页。(本来希望显示ID为112到126,结果变为105到128)

后来变为以下Sql代码查询:

SQL code 复制代码
SELECT
 *
   
FROM (
SELECT ROWNUM RN, TA. *
FROM (
select t . id ID, o. name YYB, u. name XM, t . MC
from tZDYSX t , tuser u, lborganization o
where t . cjr= u. id and u. orgid= o. orgcode and t . gx = 1 order by t . ID
) TA WHERE ROWNUM < = 20
) WHERE RN > 10
SELECT *
FROM (
SELECT ROWNUM RN, TA. *
FROM (
select t . id ID, o. name YYB, u. name XM, t . MC
from tZDYSX t , tuser u, lborganization o
where t . cjr= u. id and u. orgid= o. orgcode and t . gx = 1 order by t . ID
) TA WHERE ROWNUM < = 20
) WHERE RN > 10

结果如下:

RNIDYYBXMMC
11112某证券总部管理员幸运客户
12113某证券总部管理员风险型
13114某证券总部管理员tst
14115白沙网上交易安昌彪安客户正常
15118某证券总部管理员213
16119某证券总部管理员客户号包含1008
17120某证券总部管理员aaa
18123某证券总部管理员ssssssss
19124某证券总部管理员www
20126某证券总部管理员123123

10 rows selected

看来结果是正确的。

总结:第二种方法其中最内层的查询Sql代码

select
 t
.
id ID,
 o.
name
 YYB,
u.
name
 XM,
 t
.
MC  
from tZDYSX t , tuser u, lborganization o
where t . cjr= u. id and u. orgid= o. orgcode and t . gx = 1 order by t . ID

表示不进行翻页的原始查询语句。ROWNUM <= 20和RN > 10控制分页查询的每页的范围。
第二种方法在大多数情况拥有较高的效率。分页的目的就是控制输出结果集大小,在上面的分页查询语句中,这种考虑主要体现在WHERE ROWNUM <= 20这句上。

选择第11到20条记录存在两种方法,第二种方法正是在查询的第二层通过ROWNUM <= 20来控制最大值,在查询的最外层控制最小值。而第一种方法是去掉查询第二层的WHERE ROWNUM <= 20语句,在查询的最外层控制分页的最小值和最大值。

一般来说,第二个查询的效率比第一个高得多,这是由于CBO 优化模式下,Oracle可以将外层的查询条件推到内层查询中,以提高内层查询的执行效率。对于第二个查询语句,第2层的查询条件WHERE ROWNUM <= 20就可以被Oracle推入到内层查询中,这Oracle查询的结果一旦超过了ROWNUM限制条件,就终止查询将结果返回了。

而第一个查询语句,由于查询条件Where rn>10 and rn<=20是存在于查询的第三层,而Oracle无法将第三层的查询条件推到最内层(即使推到最内层也没有意义,因为最内层查询不知道RN代表什 么)。因此,对于第一个查询语句,Oracle最内层返回给中间层的是所有满足条件的数据,而中间层返回给最外层的也是所有数据。数据的过滤在最外层完 成,显然这个效率要比第二个查询低得多。

这种分页对于单表查询、多表查询一样有效。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值