有一个表a(fsn varchar2(32),fflag varchar2(16)),里面数据15w左右,fsn上有惟一索引,fflag有2个值,0和1,其中fflag=1大约7w,fflag=0大约10w,上面建有位图索引BTMP,执行
  select fflag,fsn from a where fflag='1';为什么不走位图索引,而走全表扫描,
而select fflag     from a where fflag='1'和select count(*) from a where fflag='1' 却走位图索引,

解决方案 »

  1.   

    初始化参数optimizer_mode默认是ALL_ROWS,这种模式下需要返回所有数据,如果返回的结果集超过表的1/10时,索引扫描的代价可能比全表扫描大,所以
    select fflag,fsn from a where fflag='1';为什么不走位图索引,而走全表扫描
    而select fflag from a where fflag='1'和select count(*) from a where fflag='1' 都不需要所有数据,所以走位图索引
      

  2.   

    那位图索引就比较适用于低基数的count(*)或返回数据很少的情况了
      

  3.   

    哦哦 ,我也想起来了  一下脑壳卡了  
     是所有的索引 在一次取数据占表所有数据的1/10时候 ,oracle 就会采用全表扫描,因为这个时候用索引取反而更慢
      

  4.   


    真强大,那应该把optimizer_mode参数设置成什么呢
      

  5.   

    而select fflag from a where fflag='1'和select count(*) from a where fflag='1' 都不需要所有数据,所以走位图索引
    这个说话不完全对,关键是,你可以查看执行计划,上面两个查询通过扫描位图索引而不需要访问表就得到结果,而选择了fsn字段后,扫描索引+扫描表的成本大于直接扫描表的成本,所以采用全表扫描。
      

  6.   

    optimizer_mode不需要设置成其它的了,10g以后都默认基于cost