Oracle分页查询性能优化代码详解
对于数据库中表的数据的Web显示,如果没有展示顺序的需要,而且因为满足条件的记录如此之多,就不得不对数据进行分页处理。常常用户并不是对所有数据都感兴趣的,或者大部分情况下,他们只看前几页。
通常有以下两种分页技术可供选择。
Select*from( Selectrownumrn,t.*fromtablet) Wherern>&minnumandrn<=&maxnum 或者 Select*from( Selectrownumrn,t.*fromtabletrownum<=&maxnum) Wherern>&minnum
看似相似的分页语句,在响应速度上其实有很大的差别。来看一个测试过程,首先创建一个测试表。
SQL>createtabletestasselect*fromdba_objects;
并反复地插入相同数据。
SQL>insertintotestselect*fromtest;
最后,查询该表,可以看到该表的记录数约为80万条。
SQL>selectcount(*)fromtest COUNT(*) ---------- 831104
现在分别采用两种分页方式,在第一种分页方式中:
SQL>select*from( 2selectrownumrn,t.*fromtestt) 3wherern>0andrn<=50; 已选择50行。 已用时间:00:00:01.03 ExecutionPlan ---------------------------------------------------------- 0SELECTSTATEMENTOptimizer=CHOOSE(Cost=10Card=65Bytes=12350) 10VIEW(Cost=10Card=65Bytes=12350) 21COUNT 32TABLEACCESS(FULL)OF'TEST'(Cost=10Card=65Bytes=5590) Statistics ---------------------------------------------------------- 0recursivecalls 0dbblockgets 10246consistentgets 0physicalreads 0redosize ……
可以看到,这种方式查询第一页的一致性读有10246个,结果满足了,但是效率是很差的,如果采用第二种方式:
SQL>select*from( 2selectrownumrn,t.*fromtestt 3whererownum<=50) 4wherern>0; 已选择50行。 已用时间:00:00:01.00 ExecutionPlan ---------------------------------------------------------- 0SELECTSTATEMENTOptimizer=CHOOSE(Cost=10Card=50Bytes=9500) 10VIEW(Cost=10Card=50Bytes=9500) 21COUNT(STOPKEY) 32TABLEACCESS(FULL)OF'TEST'(Cost=10Card=65Bytes=5590) Statistics ---------------------------------------------------------- 0recursivecalls 0dbblockgets 82consistentgets 0physicalreads 0redosize ……
得到了同样的结果,一致性读只有82个,从以上的例子可以看到,通过把rownum引入到第二层,却得到了一个完全不一样的执行计划,注意在执行计划中的stopkey,它是8i引入的新操作,这种操作专门为提取Topn的需求做了优化。
从上面的例子可以再想到,因为stopkey的功能影响到了分页的一致性读的多少,会不会越往后翻页速度就越慢呢?事实也的确如此,例如:
SQL>select*from( 2selectrownumrn,t.*fromtestt 3whererownum<=10000) 4wherern>9950; 已选择50行。 已用时间:00:00:01.01 Statistics ---------------------------------------------------------- 0recursivecalls 0dbblockgets 2616consistentgets 0physicalreads 0redosize ……
选择靠后一点的数据时,逻辑读开始变大,当选择到最后几页时,一致性读已经与上面的相似了。
SQL>select*from( 2selectrownumrn,t.*fromtestt 3whererownum<=800000) 4wherern>799950; 已选择50行。 已用时间:00:00:01.03 Statistics ---------------------------------------------------------- 0recursivecalls 0dbblockgets 10242consistentgets 0physicalreads 0redosize ……
不过,所幸的是,大部分的用户只看开始5%的数据,而没有兴趣看最后面的数据,通过第二种改良的分页技术,可以方便快速地显示前面的数据,而且不会让用户感觉到慢。
总结
以上就是本文关于Oracle分页查询性能优化代码详解的全部内容,希望对大家有所帮助。欢迎大家参阅本站其他有关专题,有什么问题可以随时留言,小编会及时回复大家的。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。