问题:没建索引导致查询结果耗时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号都不同的字段作为聚集索引也不符合“大数目的不同值情况下不应建立聚合索引”规则;当然,这种情况只是针对用户经常修改记录内容,特别是索引项的时候会负作用,但对于查询速度并没有影响(/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 = 'all'
group by key, searchtype
order by searchnum desc) where rownum < 100;
上面sql语句执行,发现耗时主要花费在order by上,即使在时间上建了索引,查询耗时仍然没什么改进。现在问题聚焦在怎么改善order by的性能上。解决方法是在时间上建立倒序索引(/Linux/2013-07/)。补充一句:oracle存储索引采用的是B*树结构,建立的索引默认是asc升序的。采用倒叙索引查询耗时从5秒多降至2秒甚至1秒以内。如果查询时间跨度过大,耗时在2秒左右。还有个问题是不使用rownum,会走索引,耗时在一秒以内。如果加上就不走索引了,耗时一秒多。因为要取表的前100行,rownum必须要,加上了就得全表扫描,耗时会有所增加,甚是头疼!
疑问:倒叙索引是怎么提高order by语句的查询性能的?