我的一个xxfl表里有个jgsj字段(日期型),对它建立了索引。然后执行select count(*) from xxfl where jllx='0' and scbj=0  and (jgsj between to_date('2008-08-27 00:00:09','yyyy-mm-dd hh24:mi:ss') and to_date('2008-08-27 01:00:09','yyyy-mm-dd hh24:mi:ss')) and sbbh=6053;查看执行计划:
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=81 Card=1 Bytes=7)
   1    0   SORT (AGGREGATE)
   2    1     INDEX (RANGE SCAN) OF 'JGSJ_IDX' (NON-UNIQUE) (Cost=81 C
          ard=11979 Bytes=83853)
然后再执行select count(*) from xxfl where jllx='0' and scbj=0  and (jgsj between to_date('2008-08-27 00:00:09','yyyy-mm-dd hh24:mi:ss') and to_date('2008-08-27 10:00:09','yyyy-mm-dd hh24:mi:ss')) and sbbh=6053;
执行计划为:
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=2593 Card=1 Bytes=12
          )   1    0   SORT (AGGREGATE)
   2    1     PARTITION HASH (ALL)
   3    2       TABLE ACCESS (FULL) OF 'XXFL' (Cost=2593 Card=244 Byte
          s=2928)这两个sql语句基本相同,不同的是查询的日期稍微有点差别,为什么一个用到了索引,另外一个没有用到十分的不解啊

解决方案 »

  1.   

    根据表和index的统计分析数据,oracle会自动选择执行计划。
    确保你的统计信息是正确的。如果你的数据分布主要在0点到10点间的话,应用full scan是对的。
      

  2.   

    可能是索引和表的统计信息不准确, 造成CBO计算错误吧.
      

  3.   


    INDEX (RANGE SCAN) OF 'JGSJ_IDX' (NON-UNIQUE) (Cost=81 Card=11979 Bytes=83853)
     
    从你的第一个语句的执行计划中可以看出 从'2008-08-27 00:00:09‘ 到 '2008-08-27 01:00:09'大概有 12000条记录,大概占总记录的2%左右,所以采用索引。
    从你的说明看,从'2008-08-27 00:00:09‘ 到 '2008-08-27 10:00:09'可能会有10倍这个数量,就是20%左右。而通常超过5%-10%,oracle会选择全表扫描。