Oracle 千万级别数据查询优化
说明:平时很少接触到大数据分页,今天有兴趣在数据库插入1000万条数据进行测试,经过查询相关资料得到如下说明:
笔者在工作中有一上百万条记录的表,在jsp页面中需对该表进行分页显示,便考虑用rownum来做,下面是具体方法(每页显示20条):
语句:"select * from tabname where rownum<20 order by name"
但却发现oracle却不能按自己的意愿来执行,而是先随便取20条记录,然后再 order by,后经咨询oracle,说rownum确实就这样,想用的话,只能用子查询来实现先排序,后rownum,方法如下:
"select * from (select * from tabname order by name) where rownum<20",但这样一来,效率会较低很多。
后经笔者试验,只需在order by 的字段上加主键或索引即可让oracle先按该字段排序,然后再rownum;方法不变:
"select * from tabname where rownum<20 order by name"
----------------------------------------------------------------
涉及到大数据量的查询时我们一般不会想要全部查看,而只是想要汇总、根据条件筛选、查询前面几页数据等。鉴于此用上面的解决方案却不能查询从21到40之间的数据,特修改语句如下:
select * from ( select s.*,rownum rowN from tabname s order by stuno desc ) m where m.rowN between 200 and 300
使用之后才发现效率还是比较慢,因为嵌套查询内部每次都要检索tabname的所有数据,故在此修改如下:
select * from ( select s.*,rownum rowN from tabname s where rownum<300 order by stuno desc ) m where m.rowN between 200 and 300
因为查询的是前200到300之间的数据,所以没有比较检索表中所有数据,故在嵌套查询内部加了个rownum<300进行筛选。当我们越是往后面分页,那么嵌套查询内部数据越大,效率就越低,但是如果只考虑查询前面几页数据,无疑是最好的方式。