解决方案 »

  1.   

    不知道你用的是什么版本的库,你对组合索引的理解没有错。但是一般情况下,貌似oracle会根据自己CBO的算法来进行解析一个sql,然后找到最优的方式去执行,就好比有的时候建索引并不是最好的优化方式。
      

  2.   


    您的意思是说,在我说的那种情况下,理论上(name,time)索引是没有(time,name)高的,但是Oracle根据情况进行了优化,所以体现出来的还是(name,time)更好么?
    我用的11g
      

  3.   


    建表和查询语句,以及收集统计信息如下:
    可以看得出第二个语句的buffers还是小于第一个语句,我把object_type全改成了a,按理说执行(type, id )应该遍历的比(id, type)的范围更广吧我理解的,感觉应该是第二个语句buffers更大
      

  4.   

    说一句,就一句:
    如果你的一列中的数据全是abc,那你索引他干毛线用?
      

  5.   

    它是当你有前导列时,条件中只有前导列这个条件时也会用到组合索引,不用两个列作为条件。
    比如
    (A,B)建了组合索引
    当WHERE A='sf'时会用到索引的
    而WHERE B='sd'是不会用到组合索引的。
      

  6.   

    感谢各位回答了
    我自己又仔细分析了一下,在excel中一行一行手工分析了一下,其实两种查询应该是一样的,因为Oracle的组合索引是,优先按照前面的列排序,前面的列一致的情况下按照下一列排序查询时,第一组合列首先充当于一个类似刹车器的功能,扫描到超过where条件,就停止查询,这样也是我的第一条语句(范围在前)
    而在第一组合列一致的情况下,第二组合列就开始充当刹车器,所以当我执行我的第二条语句(等值在前)时,虽然object_type已经被我全设成a,没有过滤功能了,但是在type一致时,第二列的object_id启动排序充当刹车器,所以还是扫描到2000自动停止了不会像我最一开始说的一直扫描下去,所以我说的这种极端情况,应该是无论谁在前谁在后,效果是一样的,区别无非是被第一组合条件限定或是第二组合条件限定的问题我后来重新建表,重建弄了一次,结果真就一样了,丝毫不差
    估计是因为我昨天在这个表上折腾太多别的操作了,索引又没重建,不定什么地方乱了
    因为想到了后面的列也能充当刹车器的事,我后来又试验了下
    建立了个三列索引(object_type, object_id, owner),然后把object_type全给a,object_id给成1,2,3这三个值
    当我查object_type=a and object_id >=1 and object_id <=2 果然比object_type=a and object_id >=1 and object_id <= 3快了近一倍
    证实了我的猜想,老大没了,老二顶了上去在2最后的位置产生了刹车效果
      

  7.   

    我今天试了一下,感觉你应该没有重新收集统计信息。如果重新收集统计信息的话,应该都走table access full。不会走索引。我用的是80万的数据量
      

  8.   

    本帖最后由 wildwave 于 2014-08-05 10:13:49 编辑
      

  9.   

    我觉得组合索引的选择看所在列的范围吧,
    比如ID,TYPE查询,ID是范围,TYPE是等值
    如果1千万条数据每个TYPE都不一样,ID在一个较小的范围内,把索引建成ID,type顺序的,肯定没有TYPE,ID的顺序效率高