多个平等的索引
当SQL语句的执行路径可以使用分布在多个表上的多个索引时 ORACLE会同时使用多个索引并在运行时对它们的记录进行合并 检索出仅对全部索引有效的记录
在ORACLE选择执行路径时唯一性索引的等级高于非唯一性索引 然而这个规则只有当WHERE子句中索引列和常量比较才有效如果索引列和其他表的索引类相比较 这种子句在优化器中的等级是非常低的
如果不同表中两个想同等级的索引将被引用 FROM子句中表的顺序将决定哪个会被率先使用 FROM子句中最后的表的索引将有最高的优先级
如果相同表中两个想同等级的索引将被引用 WHERE子句中最先被引用的索引将有最高的优先级
举例
DEPTNO上有一个非唯一性索引EMP_CAT也有一个非唯一性索引
SELECTENAME
FROMEMP
WHEREDEPT_NO=
ANDEMP_CAT=A;
这里DEPTNO索引将被最先检索然后同EMP_CAT索引检索出的记录进行合并 执行路径如下
TABLEACCESSBYROWIDONEMP
ANDEQUAL
INDEXRANGESCANONDEPT_IDX
INDEXRANGESCANONCAT_IDX
等式比较和范围比较
当WHERE子句中有索引列 ORACLE不能合并它们ORACLE将用范围比较
举例
DEPTNO上有一个非唯一性索引EMP_CAT也有一个非唯一性索引
SELECTENAME
FROMEMP
WHEREDEPTNO>
ANDEMP_CAT=A;
这里只有EMP_CAT索引被用到然后所有的记录将逐条与DEPTNO条件进行比较 执行路径如下
TABLEACCESSBYROWIDONEMP
INDEXRANGESCANONCAT_IDX
不明确的索引等级
当ORACLE无法判断索引的等级高低差别优化器将只使用一个索引它就是在WHERE子句中被列在最前面的
举例
DEPTNO上有一个非唯一性索引EMP_CAT也有一个非唯一性索引
SELECTENAME
FROMEMP
WHEREDEPTNO>
ANDEMP_CAT>A;
这里 ORACLE只用到了DEPT_NO索引 执行路径如下
TABLEACCESSBYROWIDONEMP
INDEXRANGESCANONDEPT_IDX
译者按我们来试一下以下这种情况
SQL>selectindex_nameuniquenessfromuser_indexeswheretable_name=EMP;
INDEX_NAMEUNIQUENES
EMPNOUNIQUE
EMPTYPENONUNIQUE
SQL>select*fromempwhereempno>=andemp_type=A;
norowsselected
ExecutionPlan
SELECTSTATEMENTptimizer=CHOOSE
TABLEACCESS(BYINDEXROWID)OFEMP
INDEX(RANGESCAN)OFEMPTYPE(NONUNIQUE)
虽然EMPNO是唯一性索引但是由于它所做的是范围比较 等级要比非唯一性索引的等式比较低!