解决方案 »

  1.   

    你想让优化器优化器走 idx_table_1 而实际却走 idx_table_2 是吗?
    你这样写看看执行计划:
     slect * from table where  datetime = to_date('22-10-2014 21:55:00', 'dd-mm-yyyy hh24:mi:ss') and  cid =1
    union 
      slect * from table where  datetime = to_date('22-10-2014 21:55:00', 'dd-mm-yyyy hh24:mi:ss') and  cid =2
    union 
     slect * from table where  datetime = to_date('22-10-2014 21:55:00', 'dd-mm-yyyy hh24:mi:ss') and  cid =1
     然后在看看这个执行计划,对比一下
     slect * from table where  datetime = to_date('22-10-2014 21:55:00', 'dd-mm-yyyy hh24:mi:ss') and  cid in (1,2,3) 
      

  2.   

    是的, 使用 datetime = ‘’ and cid ='1'的话肯定是 走 PK_TABLE_1主键了,但是我后面 in的字符有80十多个,就不能这么一直的union。
    我主要想知道,为什么不会走  idx_table_1?
    in不是也会使用索引的吗?
      

  3.   

    oracle目前采用最优方案,所以肯定走idx_table_2索引比另外两个效率高。
    下面说下我对这个现象的理解:
    你这个sql句子对于datetime而言是等值查询,对于cid相当于范围查询,而
    oracle的联合索引,字段顺序只有是当等值查询在前,范围查询在后效率才高,
    使用联合索引才最优。所以你试试idx_table_1(索引 Unique) key  cid,datetime
    这个索引改成这样idx_table_1(索引 Unique) key  datetime,cid,也就是调换索引
    列的顺序。(当然如果要看哪种情况查询多一点,如果这个sql只是偶尔执行一次,
    那就不要随意改动了。)这样oracle大概就会使用联合索引了。
      

  4.   

    优化通过计算得出的走idx_table_2是最优的,如果你可以通过提示是优化器走idx_table_1
    /* index(表名,索引名) */ 
      

  5.   

    oracle目前采用最优方案,所以肯定走idx_table_2索引比另外两个效率高。
    下面说下我对这个现象的理解:
    你这个sql句子对于datetime而言是等值查询,对于cid相当于范围查询,而
    oracle的联合索引,字段顺序只有是当等值查询在前,范围查询在后效率才高,
    使用联合索引才最优。所以你试试idx_table_1(索引 Unique) key  cid,datetime
    这个索引改成这样idx_table_1(索引 Unique) key  datetime,cid,也就是调换索引
    列的顺序。(当然如果要看哪种情况查询多一点,如果这个sql只是偶尔执行一次,
    那就不要随意改动了。)这样oracle大概就会使用联合索引了。

    我现在更改成了 pk_table_1(主键 Unique) key  datetime,cid
                             idx_table_1(索引 Unique) key  cid,datetime
                                idx_table_2(索引 Normal) key  cid
    仍然跟之前的执行计划结果一样。
    索引会区分 联合字段的前后顺序吗?我使用 exists的执行计划结果也跟in的一样?
      

  6.   

    第一点。先纠正下,我上面说错了,in()这个相当于等值查询,所以你的语句组合索引顺序和这个句子执行计划
    没有关系。
    第二点。刚才只是我想象了一下执行计划(因为你具体表中每列的重复率什么的我都不知道),
    真正oracle执行计划是按照最优执行的,所以肯定走idx_table_2效率比走另外两个索引效率高,
    楼主可以再语句里面加入/*+index(idx_table_1)*/*  让oracle强制走组合索引,综合效率肯定比
    idx_table_2低。
    第三点。回答你的索引区分前后顺序吗? 回答是肯定要区分的,对于索引两列都是等值查询时候,
    前后顺序怎么样效率一样,但是一列为等值,一列为范围,要把等值列放到前面,这样索引效率更高;
    但是如果建的组合索引,查询时候只查询组合索引中一列,这时候只查询的这一列必须放在组合索引
    前面,要不然组合索引失效,最后执行计划不是index range scan,而是table access full,也就是最后
    走的全表扫描。关于组合索引这一点,我记得梁老师的收获,不止oracle里面有讲,刚才看了下,在书的272页往后有
    详细介绍,楼主方便可以去看。我自己组织的语言略显粗糙,作为参考看看就好。
      

  7.   

    datetime字段选择性不高,或者不是date类型。如果非以上,重新采集表的统计信息
    另外,并非重复索引,索引!=约束,只不过主键/唯一键是通过索引来实现了,如果创建时不存在对应的索引,则会自动创建
      

  8.   

    cid和datetime组合是唯一的,所以应该不是重复率的问题吧?所以我也是因为觉得是唯一的,应该走组合索引效率会高点吧?
    谢谢你的一直回复。
      

  9.   

    datetime是 date类型。
    "另外,并非重复索引,索引!=约束" 谢谢解答,一直就把约束当做索引的使用了
      

  10.   

    datetime是 date类型。
    "另外,并非重复索引,索引!=约束" 谢谢解答,一直就把约束当做索引的使用了
    7楼DAVE回复很犀利,按照他说得试试。