你想让优化器优化器走 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)
你这样写看看执行计划:
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)
我主要想知道,为什么不会走 idx_table_1?
in不是也会使用索引的吗?
下面说下我对这个现象的理解:
你这个sql句子对于datetime而言是等值查询,对于cid相当于范围查询,而
oracle的联合索引,字段顺序只有是当等值查询在前,范围查询在后效率才高,
使用联合索引才最优。所以你试试idx_table_1(索引 Unique) key cid,datetime
这个索引改成这样idx_table_1(索引 Unique) key datetime,cid,也就是调换索引
列的顺序。(当然如果要看哪种情况查询多一点,如果这个sql只是偶尔执行一次,
那就不要随意改动了。)这样oracle大概就会使用联合索引了。
/* index(表名,索引名) */
下面说下我对这个现象的理解:
你这个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的一样?
没有关系。
第二点。刚才只是我想象了一下执行计划(因为你具体表中每列的重复率什么的我都不知道),
真正oracle执行计划是按照最优执行的,所以肯定走idx_table_2效率比走另外两个索引效率高,
楼主可以再语句里面加入/*+index(idx_table_1)*/* 让oracle强制走组合索引,综合效率肯定比
idx_table_2低。
第三点。回答你的索引区分前后顺序吗? 回答是肯定要区分的,对于索引两列都是等值查询时候,
前后顺序怎么样效率一样,但是一列为等值,一列为范围,要把等值列放到前面,这样索引效率更高;
但是如果建的组合索引,查询时候只查询组合索引中一列,这时候只查询的这一列必须放在组合索引
前面,要不然组合索引失效,最后执行计划不是index range scan,而是table access full,也就是最后
走的全表扫描。关于组合索引这一点,我记得梁老师的收获,不止oracle里面有讲,刚才看了下,在书的272页往后有
详细介绍,楼主方便可以去看。我自己组织的语言略显粗糙,作为参考看看就好。
另外,并非重复索引,索引!=约束,只不过主键/唯一键是通过索引来实现了,如果创建时不存在对应的索引,则会自动创建
谢谢你的一直回复。
"另外,并非重复索引,索引!=约束" 谢谢解答,一直就把约束当做索引的使用了
"另外,并非重复索引,索引!=约束" 谢谢解答,一直就把约束当做索引的使用了
7楼DAVE回复很犀利,按照他说得试试。