所以这就是CBO的好处呀。
当数据库记录很少的时候,CBO会发现采用full-table scan要比index-scan更好。
应该说,并不是一定动用索引就好。
CBO的计算往往和索引的cluster ratio,索引页的level数,数据块的cluster ratio等等有关,理论上动用索引每一级会增加一个logic read IO。因此当数据量很小的时候,FULL-TABLE SCAN缺是一个不错的选择。

解决方案 »

  1.   

    and mk.status is null 这句不会使用索引
      

  2.   

    但是f表不是小表,比较大
    mk.status is null 这句不会使用索引  -- 这句话很有道理,我去改改但:f表 为什么是全表扫描呢?
      

  3.   

    and f.company_id = fp.ID(+)  
    and f.postnr = p.postnr_c(+)  f全表扫描可能与(+)有关系.具体没测试过. 觉得优化器在工作的时候有些奇怪(没有完全搞明白). 而且看优化器工作的吧,有时候一个表只有几百条记录,如果你建了一个索引,测试计划中显示也使用了索引的...
      

  4.   

    我把 mk.status 里的空值赋为‘1’,然后查询时使用mk.status = '1', 速度快了很多但f还是全表扫描,真奇怪,f有150万条数据,不能算小表吧?
      

  5.   

    就你的表连接语句看,oralce必然选f作为驱动表,f的其他非连接条件没有用索引列,因此f用全表扫描
      

  6.   

    from  fp,p,  f,mk 是从左向右 还是从右向左 解析? 这种情况下是以f作为驱动表, 还是以mk作为驱动表?  我记得看过一篇文章说要把作为驱动表的表放在最后,也记得不太清楚了,高手能指点一二吗?
      

  7.   

    CBO不会使用固定的解析顺序,而是按FF(filter factor)来决定驱动表.如dinya2003所说,右连接已经决定f表的所有数据都必须访问,f不做驱动表都不行,如果去掉(+),驱动表才有可能变化。RBO使用固定的从右向左的解析顺序
      

  8.   

    出现and mk.status is null 
    或者like 后面的%在前面的话,索引都将不起作用
      

  9.   

    and f.company_id = fp.ID(+)  
    and f.postnr = p.postnr_c(+) 
    可我觉得出现这样的情况应该是fp 和 p 这两个表的所有数据都必须访问啊而且,同样这个语句,同样的索引,在两台server运行时,其中一台速度比较快,而另一台就慢得不行,我查了一下执行计划,发现不一样,第一台就没有对f进行全表扫描,第二台就对f进行全表扫描,我觉得很奇怪。
      

  10.   

    在两台不同的Server上,如果是同样的语句执行计划不一样,建议你检查一下你的Optimizer Mode,很可能是两台Server设置不一样;也有可能两台Server的Optimizer Mode一样,用的都是Choose,但表的统计分析信息不同,你可以把查询里面涉及的表都统计分析一下,试着再执行。
       另外,你还可以在SQL语句里加上强制的提示符/*+ RULE*/ ,你会发现执行计划会一样,但是基于规则的优化方法并不推荐使用。
      

  11.   

    两台server的Optimizer Mode一样,用的都是Choose
    不好意思,我不会对表进行统计分析,能指点一下吗?谢谢!
      

  12.   

    统计表
    SQL> call dbms_stats.gather_table_stats('ownername','tablename');