oracle千万级数据查询优化

来源:互联网 发布:知乎 办公室装修 编辑:程序博客网 时间:2024/05/17 06:35
需求:组合查询,按条件统计某几个字段取前100条记录
问题:没建索引导致查询结果耗时5秒多,不能忍受。

解决方法:
建索引,在哪个字段建?
       在这里先提下Oracle的sql语句的执行。oracle在执行sql语句之前会用优化器Optimizer对sql语句进行解析,解析出最优的执行计划再执行,这样所花费的时间最少,效率最快。
优化器优化方式有两种:
     (1)基于规则的优化(Rule-Based Optimization,简称为RBO) ,优化器在解析sql的时候会遵循oralce的一些内部规则,比如在遇到where子语句中某个字段上有索引就用索引。
     (2)基于代价的优化(Cost-Based Optimization,简称为CBO),基于代价主要指消耗cpu和内存,优化器若使用这种方式解析,主要是参考表和索引的统计信息,比如表大小,行数,行长度等信息。

        根据上面两条,结合实际情况,最后在时间字段上建了索引。在实际应用中,因为ID号是自动生成的,我们并不知道每条记录的ID号,所以我们很难在实践中用ID号来进行查询。这就使让ID号这个主键作为聚集索引成为一种资源浪费。其次,让每个ID号都不同的字段作为聚集索引也不符合“大数目的不同值情况下不应建立聚合索引”规则;当然,这种情况只是针对用户经常修改记录内容,特别是索引项的时候会负作用,但对于查询速度并没有影响(http://blog.csdn.net/chenjinjie/article/details/1628355#comments)。

sql语句如下:

select key,       searchtype from(select keyword,               searchtype,               sum(search_num) searchnum,               sum(searchuser_num) searchusernum,               sum(order_num) ordernum,               sum(orderuser_num) orderusernum,               sum(browse_num) browsenum,               sum(browseuser_num) browseusernum          from rp_demo_test t         where t.update_time between '20150101' and '20150131'          and t.searchtype = 'all'         group by key, searchtype          order by searchnum desc) where rownum < 100;          

       上面sql语句执行,发现耗时主要花费在order by上,即使在时间上建了索引,查询耗时仍然没什么改进。现在问题聚焦在怎么改善order by的性能上。解决方法是在时间上建立倒序索引(http://www.linuxidc.com/Linux/2013-07/87433.htm)。补充一句:oracle存储索引采用的是B*树结构,建立的索引默认是asc升序的。采用倒叙索引查询耗时从5秒多降至2秒甚至1秒以内。如果查询时间跨度过大,耗时在2秒左右。还有个问题是不使用rownum,会走索引,耗时在一秒以内。如果加上就不走索引了,耗时一秒多。因为要取表的前100行,rownum必须要,加上了就得全表扫描,耗时会有所增加,甚是头疼!

疑问:倒叙索引是怎么提高order by语句的查询性能的?


0 0
原创粉丝点击