select mbrid,min(dos) min_dos from
(select distinct mbrid,dos from fi05 where 
(
dx1 in('40201', '40211', '40291', '40401', '40411',  '40491','4280', '4281', '42820','42821','42822','42823',' 42840','42841','42842','42843')
or dx2 in('40201', '40211', '40291', '40401', '40411',  '40491','4280', '4281', '42820','42821','42822','42823',' 42840','42841','42842','42843')
or dx3 in('40201', '40211', '40291', '40401', '40411',  '40491','4280', '4281', '42820','42821','42822','42823',' 42840','42841','42842','42843')
or dx4 in('40201', '40211', '40291', '40401', '40411',  '40491','4280', '4281', '42820','42821','42822','42823',' 42840','42841','42842','42843')
or dx5 in('40201', '40211', '40291', '40401', '40411',  '40491','4280', '4281', '42820','42821','42822','42823',' 42840','42841','42842','42843')
or dx6 in('40201', '40211', '40291', '40401', '40411',  '40491','4280', '4281', '42820','42821','42822','42823',' 42840','42841','42842','42843')
or dx7 in('40201', '40211', '40291', '40401', '40411',  '40491','4280', '4281', '42820','42821','42822','42823',' 42840','42841','42842','42843')
or dx8 in('40201', '40211', '40291', '40401', '40411',  '40491','4280', '4281', '42820','42821','42822','42823',' 42840','42841','42842','42843')
or dx9 in('40201', '40211', '40291', '40401', '40411',  '40491','4280', '4281', '42820','42821','42822','42823',' 42840','42841','42842','42843')

and 
(
    
     (cpt between '99201' and '99205') or (cpt between '99211' and '99215') or (cpt between '99241' and '99245') or (cpt between '99271' and '99275')
          or (cpt between '99301' and '99313') or (cpt between '99315' and '99316') or (cpt between '99318' and '99337') or (cpt between '99341' and '99350')
          or (cpt between '99354' and '99355') or (cpt between '99381' and '99387') or (cpt between '99391' and '99397') or (cpt between '99401' and '99429')
          or (cpt= '99450') or (cpt between '99455' and '99456') or  (cpt between '99217' and '99220')  or (cpt between '99234' and '99236')
          or (cpt1 between '99201' and '99205') or (cpt1 between '99211' and '99215') or (cpt1 between '99241' and '99245') or (cpt1 between '99271' and '99275')
          or (cpt1 between '99301' and '99313') or (cpt1 between '99315' and '99316') or (cpt1 between '99318' and '99337') or (cpt1 between '99341' and '99350')
          or (cpt1 between '99354' and '99355') or (cpt1 between '99381' and '99387') or (cpt1 between '99391' and '99397') or (cpt1 between '99401' and '99429')
          or (cpt1= '99450') or (cpt1 between '99455' and '99456')or  (cpt1 between '99217' and '99220')  or (cpt2 between '99234' and '99236')
          or (cpt2 between '99201' and '99205') or (cpt2 between '99211' and '99215') or (cpt2 between '99241' and '99245') or (cpt2 between '99271' and '99275')
          or (cpt2 between '99301' and '99313') or (cpt2 between '99315' and '99316') or (cpt2 between '99318' and '99337') or (cpt2 between '99341' and '99350')
          or (cpt2 between '99354' and '99355') or (cpt2 between '99381' and '99387') or (cpt2 between '99391' and '99397') or (cpt2 between '99401' and '99429')
          or (cpt2= '99450') or (cpt2 between '99455' and '99456')or  (cpt2 between '99217' and '99220')  or (cpt2 between '99234' and '99236')
          or (cpt3 between '99201' and '99205') or (cpt3 between '99211' and '99215') or (cpt3 between '99241' and '99245') or (cpt3 between '99271' and '99275')
          or (cpt3 between '99301' and '99313') or (cpt3 between '99315' and '99316') or (cpt3 between '99318' and '99337') or (cpt3 between '99341' and '99350')
          or (cpt3 between '99354' and '99355') or (cpt3 between '99381' and '99387') or (cpt3 between '99391' and '99397') or (cpt3 between '99401' and '99429')
          or (cpt3= '99450') or (cpt3 between '99455' and '99456')or  (cpt3 between '99217' and '99220')  or (cpt3 between '99234' and '99236')
          or (cpt4 between '99201' and '99205') or (cpt4 between '99211' and '99215') or (cpt4 between '99241' and '99245') or (cpt4 between '99271' and '99275')
          or (cpt4 between '99301' and '99313') or (cpt4 between '99315' and '99316') or (cpt4 between '99318' and '99337') or (cpt4 between '99341' and '99350')
          or (cpt4 between '99354' and '99355') or (cpt4 between '99381' and '99387') or (cpt4 between '99391' and '99397') or (cpt4 between '99401' and '99429')
          or (cpt4= '99450') or (cpt4 between '99455' and '99456')or  (cpt4 between '99217' and '99220')  or (cpt4 between '99234' and '99236') 
          or (cpt5 between '99201' and '99205') or (cpt5 between '99211' and '99215') or (cpt5 between '99241' and '99245') or (cpt5 between '99271' and '99275')    
          or (cpt5 between '99301' and '99313') or (cpt5 between '99315' and '99316') or (cpt5 between '99318' and '99337') or (cpt5 between '99341' and '99350')
          or (cpt5 between '99354' and '99355') or (cpt5 between '99381' and '99387') or (cpt5 between '99391' and '99397') or (cpt5 between '99401' and '99429')
          or (cpt5= '99450') or (cpt5 between '99455' and '99456')or  (cpt5 between '99217' and '99220')  or (cpt5 between '99234' and '99236')
          or (cpt6 between '99201' and '99205') or (cpt6 between '99211' and '99215') or (cpt6 between '99241' and '99245') or (cpt6 between '99271' and '99275')
          or (cpt6 between '99301' and '99313') or (cpt6 between '99315' and '99316') or (cpt6 between '99318' and '99337') or (cpt6 between '99341' and '99350')
          or (cpt6 between '99354' and '99355') or (cpt6 between '99381' and '99387') or (cpt6 between '99391' and '99397') or (cpt6 between '99401' and '99429')
          or (cpt6= '99450') or (cpt6 between '99455' and '99456')or  (cpt6 between '99217' and '99220')  or (cpt6 between '99234' and '99236')
    or(rev between '0500' and '0529') or (rev between '0570' and '0599') or (rev between '0770' and '0779') or (rev between '0820' and '0859' )
    or (rev between '0982' and '0983') or (rev = '0882')
    or(rev1 between '0500' and '0529') or (rev1 between '0570' and '0599') or (rev1 between '0770' and '0779') or (rev1 between '0820' and '0859') 
    or (rev1 between '0982' and '0983') or (rev1 = '0882')
    or (rev2 between '0500' and '0529') or (rev2 between '0570' and '0599') or (rev2 between '0770' and '0779') or (rev2 between '0820' and '0859') 
    or (rev2 between '0982' and '0983') or (rev2 = '0882')
    or (rev3 between '0500' and '0529') or (rev3 between '0570' and '0599') or (rev3 between '0770' and '0779') or (rev3 between '0820' and '0859') 
    or (rev3 between '0982' and '0983') or (rev3 = '0882')
    or (rev4 between '0500' and '0529') or (rev4 between '0570' and '0599') or (rev4 between '0770' and '0779') or (rev4 between '0820' and '0859') 
    or (rev4 between '0982' and '0983') or (rev4 = '0882')
) ) group by mbrid having count(mbrid)>=2;这样的一个sql语句,为什么where中有cpt6的时候就不适用位图检索啊,所有的字段上面都有位图索引的。就像现在这样,现在这个sql语句就不使用索引查询,直接是扫描全表。
如果把cpt6去掉了,就是在sql语句的where中去掉,它就使用索引查询。 为什么啊 ? 
高手请指点…… 最好附代码 谢谢  oracle10g

解决方案 »

  1.   

    你的bitmap索引是建立在哪个字段上的,由于bitmap锁引本身的物理和算法结构,bitmap索引是不适合做range查询的。
      

  2.   

    上面的每个字段都是有位图索引的。
    你说“bitmap索引是不适合做range查询的”  意思就是我的这样的查询条件是不适合用位图索引的啊……
    但是这个用索引查询比不用索引效率高好多啊?
    现在我就是不知道为什么加上cpt6就不执行索引了…… 都有什么可能啊! 
    我的表和索引都是建立在system表空间上的。
      

  3.   


    为什么cpt 这些字段,不用btree而用位图索引啊?
    一般唯一值比较多(且增删操作比较少的table上)的情况下才推荐使用位图索引.
      

  4.   

    我的这个就是啊,我的这个表都是查询,没有增删改操作。
    但是我的这个表里面的数据重复的特别多,好像是唯一值少的用位图所以效果才很明显吧,类似于性别一类的。
    现在关键是我的那个为什么添加上cpt6就不好用啊?
    没有他的时候就执行索引,执行的很快,有了cpt6就不好用了,执行的时候也不执行索引了,而且执行起来特别的慢。
      

  5.   

    按你这样的描述你检查一下索引的状态先
    SQL> select index_name, index_type, status, last_analyzed from user_indexes where table_name = 'FI05';
      

  6.   


    1 A9 BITMAP VALID 2009-9-28 8:37:20
    2 A8 BITMAP VALID 2009-9-28 8:37:20
    3 A7 BITMAP VALID 2009-9-28 8:37:20
    4 A6 BITMAP VALID 2009-9-28 8:37:20
    5 A5 BITMAP VALID 2009-9-28 8:37:20
    6 A4 BITMAP VALID 2009-9-28 8:37:20
    7 A3 BITMAP VALID 2009-9-28 8:37:20
    8 A29 BITMAP VALID 2009-9-28 8:37:20
    9 A28 BITMAP VALID 2009-9-28 8:37:20
    10 A27 BITMAP VALID 2009-9-28 8:37:20
    11 A25 BITMAP VALID 2009-9-28 8:37:20
    12 A24 BITMAP VALID 2009-9-28 8:37:20
    13 A23 BITMAP VALID 2009-9-28 8:37:20
    14 A22 BITMAP VALID 2009-9-28 8:37:20
    15 A21 BITMAP VALID 2009-9-28 8:37:20
    16 A20 BITMAP VALID 2009-9-28 8:37:20
    17 A2 BITMAP VALID 2009-9-28 8:37:20
    18 A19 BITMAP VALID 2009-9-28 8:37:20
    19 A18 BITMAP VALID 2009-9-28 8:37:20
    20 A17 BITMAP VALID 2009-9-28 8:37:20
    21 A16 BITMAP VALID 2009-9-28 8:37:20
    22 A15 BITMAP VALID 2009-9-28 8:37:20
    23 A14 BITMAP VALID 2009-9-28 8:37:20
    24 A13 BITMAP VALID 2009-9-28 8:37:20
    25 A12 BITMAP VALID 2009-9-28 8:37:20
    26 A11 BITMAP VALID 2009-9-28 8:37:20
    27 A10 BITMAP VALID 2009-9-28 8:37:20
    28 A26 BITMAP VALID 2009-9-28 8:45:48
    29 A1 BITMAP VALID 2009-9-28 8:37:20
    30 FI05 NORMAL VALID 2009-9-28 8:37:20这个是我的检索的结果 ,都是有效的啊…… 
    还有什么原因啊?
      

  7.   

    我发现问题的所在了。就像
    select * from fi05 where  (cpt6 between '99201' and '99205') or (cpt6 between '99211' and '99215') or (cpt6 between '99241' and '99245') or (cpt6 between '99271' and '99275')    
             or (cpt6 between '99301' and '99313') or (cpt6 between '99315' and '99316') or (cpt6 between '99318' and '99337') or (cpt6 between '99341' and '99350')
              or (cpt6 between '99354' and '99355') or (cpt6 between '99381' and '99387') or (cpt6 between '99391' and '99397') or (cpt6 between '99401' and '99429')
              or (cpt6 between '99450' and '99450')or (cpt6 between '99455' and '99456')or  (cpt6 between '99217' and '99220')  or (cpt6 between '99234' and '99236')这个语句现在就不执行索引,我发现为什么了。是因为最后面的那个cpt6 between '99450' and '99450'
    不知道为什么?但是把它改成cpt6 between '99450' and '99451' 现在就执行索引 不知道为什么啊?
    我的这个cpt6全部都是空的!跟这个有关系嘛?
    高手帮忙解决一下……
      

  8.   

    那你把条件改写成cpt6 IN ('','','')的形式,条件只有cpt6这一个条件,那么查询会使用索引吗?
      

  9.   

    改成in也是不好用的  
    如果没有那个(cpt6 between '99450' and '99450') 或者把它改成
    (cpt6 between '99450' and '99451')是会使用索引的……
      

  10.   

    好的 
    select * from fi05 where  (cpt6 between '99201' and '99205') or (cpt6 between '99211' and '99215') or (cpt6 between '99241' and '99245') or (cpt6 between '99271' and '99275')    
             or (cpt6 between '99301' and '99313') or (cpt6 between '99315' and '99316') or (cpt6 between '99318' and '99337') or (cpt6 between '99341' and '99350')
              or (cpt6 between '99354' and '99355') or (cpt6 between '99381' and '99387') or (cpt6 between '99391' and '99397') or (cpt6 between '99401' and '99429')
              or (cpt6 between '99450' and '99450')or (cpt6 between '99455' and '99456')or  (cpt6 between '99217' and '99220')  or (cpt6 between '99234' and '99236')
    这个不执行索引 执行计划是这样的
    SELECT STATEMENT, GOAL = ALL_ROWS Cost=9735 Cardinality=763125 Bytes=270146250 Time=117
     TABLE ACCESS FULL Object owner=HIT Object name=FI05 Cost=9735 Cardinality=763125 Bytes=270146250 Time=117这个是执行索引的语句 
    select * from fi05 where  (cpt6 between '99201' and '99205') or (cpt6 between '99211' and '99215') or (cpt6 between '99241' and '99245') or (cpt6 between '99271' and '99275')    
             or (cpt6 between '99301' and '99313') or (cpt6 between '99315' and '99316') or (cpt6 between '99318' and '99337') or (cpt6 between '99341' and '99350')
              or (cpt6 between '99354' and '99355') or (cpt6 between '99381' and '99387') or (cpt6 between '99391' and '99397') or (cpt6 between '99401' and '99429')
              or (cpt6 between '99450' and '99451')or (cpt6 between '99455' and '99456')or  (cpt6 between '99217' and '99220')  or (cpt6 between '99234' and '99236')
    只是把cpt6 between '99450' and '99450'改成了cpt6 between '99450' and '99451'
    下面是执行计划
    SELECT STATEMENT, GOAL = ALL_ROWS Cost=8198 Cardinality=29959 Bytes=10605486 Time=99
     TABLE ACCESS BY INDEX ROWID Object owner=ZJHIT Object name=FI05 Cost=8198 Cardinality=29959 Bytes=10605486 Time=99
      BITMAP CONVERSION TO ROWIDS
       BITMAP OR
        BITMAP MERGE
         BITMAP INDEX RANGE SCAN Object owner=ZJHIT Object name=A26
        BITMAP MERGE
         BITMAP INDEX RANGE SCAN Object owner=ZJHIT Object name=A26
        BITMAP MERGE
         BITMAP INDEX RANGE SCAN Object owner=ZJHIT Object name=A26
        BITMAP MERGE
         BITMAP INDEX RANGE SCAN Object owner=ZJHIT Object name=A26
        BITMAP MERGE
         BITMAP INDEX RANGE SCAN Object owner=ZJHIT Object name=A26
        BITMAP MERGE
         BITMAP INDEX RANGE SCAN Object owner=ZJHIT Object name=A26
        BITMAP MERGE
         BITMAP INDEX RANGE SCAN Object owner=ZJHIT Object name=A26
        BITMAP MERGE
         BITMAP INDEX RANGE SCAN Object owner=ZJHIT Object name=A26
        BITMAP MERGE
         BITMAP INDEX RANGE SCAN Object owner=ZJHIT Object name=A26
        BITMAP MERGE
         BITMAP INDEX RANGE SCAN Object owner=ZJHIT Object name=A26
        BITMAP MERGE
         BITMAP INDEX RANGE SCAN Object owner=ZJHIT Object name=A26
        BITMAP MERGE
         BITMAP INDEX RANGE SCAN Object owner=ZJHIT Object name=A26
        BITMAP MERGE
         BITMAP INDEX RANGE SCAN Object owner=ZJHIT Object name=A26
        BITMAP MERGE
         BITMAP INDEX RANGE SCAN Object owner=ZJHIT Object name=A26
        BITMAP MERGE
         BITMAP INDEX RANGE SCAN Object owner=ZJHIT Object name=A26
        BITMAP MERGE
         BITMAP INDEX RANGE SCAN Object owner=ZJHIT Object name=A26 帮我看看这是为什么啊? 不知道问题出在哪里啊???
    急!!!!
      

  11.   

    哪为高手能帮忙解决一下啊 
    执行计划已经贴出去了啊……  
    cot6 的那个地段的所有的值都是空的。为什么不好用啊……
      

  12.   


    这里你的意思是cpt6 between '99450' and '99450'不改的话,是和上面一样走的fts,
    而改成了cpt6 between '99450' and '99451' 就是下面的执行计划了么。做过表的statistics没有。
      

  13.   

    你的cpt6字段有没有记录呀。 如果都是空记录的话,是全表扫描的。
      

  14.   

    表分析过了。
    我的cpt6 确实是空的。 但是为什么改成了cpt6 between '99450' and '99451'  就好用啊
    只是在这少改动一下就执行索引了啊。
    跟是不是空有关系吗? 同样是空的为什么 cpt6 between '99450' and '99451'  就执行索引啊?
      

  15.   

    分析索引的有效性:
    select 时,where条件对应的 数值在整个数据列中是少数,这样建立索引才有意义。
    比如说 一个数据库中,
    列值有三种 
    结果 1,2,5 
    其中 1有67417行,
     2 有 1行
     5 有 12
    那么对于列值为2或者5的行的查询建立索引才有效果。
      

  16.   

    cpt6 在'99450' '99451'  之间的一个都没有吗?为什么要写成 cpt6 between 99450 and 99450
    干脆改成 cpt6=99450不就得了
      

  17.   

    正是因为我写成 cpt6=99450 不好用 我才改成 cpt6 between 99450 and 99450
    cpt6 是空的 所以当然在那个区间是一个都没有的啊……