问一个老生常谈的问题,oracle何时走索引,今天遇到一个奇怪的问题,查询一个表最近七天内的数据,数据量2w条左右,全表的数据量达到50多w,根据分析的很,数据量远远没有达到1/3,如果建了索引,应该会走索引才对,可这就奇怪了,它偏偏不走索引,但是加了order by之后,它就能走索引了,更奇怪的事是加了order by再加一个没有索引的条件,它又不会走索引了,感觉直接上sql说得清楚些,如下:
全部的数据量:

符合条件的数据量:

查询最近七天的数据不会自动走索引(create_time上建了索引)(执行计划):

加了orderby之后能走索引:

再加一个没有索引的条件,又变成了不会走索引:

我知道可以使用hint让它强制走索引,但是我想了解一下oracle优化器是怎么思考,有木有大虾能解释一下不,小弟不胜感激
------解决方案--------------------
优化器CBO太难了,同等大神
------解决方案--------------------
何时走索引,不是几句话能说清楚的
这里的1/3不准确,具体的值不好说,由cbo来判断。大概的量级在1/10左右吧
cbo的思考方式是找出成本最小的那个执行计划,即执行语句所有时间的最短估计。
在Oracle 9.2的costing model中,成本的计算公式为
Cost = (
#SRds * sreadtim +
#MRds * mreadtim +
#CPUCycles / cpuspeed
) / sreadtim
where
#SRDs - number of single block reads
#MRDs - number of multi block reads
#CPUCycles - number of CPU Cycles
sreadtim - single block read time
mreadtim - multi block read time
cpuspeed - CPU cycles per second
后续版本做了一些调整,但是差距不大
在你的例子中,优化器大概认为走全表扫描效率会更高一点,但是相差不大,因此当你加上排序时,若走全表扫描,比起走索引的执行计划要多出排序的这部分成本。
将谓词条件的选择性提高,例如create_time >trunc(sysdate-2)
走索引的可能性将会更高
若非肯定,谨慎使用Hint,它可能会造成严重的性能问题
另外,优化器的很多数据来源于统计信息。如果表的统计信息不正确可能会误导优化器
可以使用dbms_stats包中的存储过程来调整统计信息