
Oracle Database Cloud Exadata Service -
版本 N/A 和更高版本
Oracle Database Backup Service -
版本 N/A 和更高版本
Oracle Database Cloud Service -
版本 N/A 和更高版本
Oracle Database - Standard Edition -
版本 8.1.7.4 和更高版本
Oracle Database - Personal Edition -
版本 8.1.7.4 和更高版本
用途
这篇文章用来解答下面的问题:为什么我的索引没有被使用?
排错步骤
“
为什么索引没有被使用
”是一个涉及面较广的问题。有很多种原因会导致索引没有被使用。下面是一些非常有用的检查列
•
表上是否存在索引?
检查您认为应该通过索引访问的表上是否真的有定义索引。那些索引可能已经被删掉或者在创建的时候就失败了 – 比
如一种可能的场景是,在对表做导入或 load 操作后,由于软件或人为错误造成索引没有被创建。下面的语句可以用
来检查索引是否存在。
SELECT index_name FROM user_indexes WHERE table_name = &Table_Name;
•
索引是否应该被使用?
Oracle 不会仅仅因为有索引存在就一定要使用索引。如果一个查询需要检索出这个表里所有的记录(比如说表之间做
连接操作),那为什么还要既访问索引的所有数据又访问表的所有数据呢?在这种情况下只访问表的数据会更快。对
所有的查询 Oracle Optimizer 会基于统计信息来计算各种访问路径,包括索引,从而选出最优的一个。
•
索引列或者索引的前置列是否在单表(
non-join
)查询的
Where
条件中(
predicate list
)?
如果不是,至少需要索引前置列在查询谓词列表中,查询才能使用索引。(例外:请见下面的 Skip Scan)。
示例:
在列 EMP.EMPNO 上定义了单列索引 EMPNO_I1,同时在列 EMP.EMPNO 和 EMP.DEPT 上定义了联合索引
EMPNO_DEPT_I2(EMP.EMPNO为索引前置列)。那么必须在查询谓词列表中(where从句)使用列
EMP.EMPNO,优化器才能使用这两个索引中的某一个。
SELECT ename, sal, deptno FROM emp WHERE empno<100;
例外:
◦ 只要索引中包含查询所需的所有列, 而且至少有一个索引列中含有非空约束,CBO 就能够使用索引快速全扫描
(INDEX_FFS)。执行 INDEX_FFS 不需要索引前置列。需要注意的是 INDEX_FFS 不能保证返回的行是排序的。
结果的顺序是与读取索引块的顺序一致的,只有当使用了 'order by' 子句时才能保证结果是排序的。请参照:
文档 1549181.1 https://support.oracle.com/epmos/faces/DocumentDisplay?_a...
第2页 共9页 2025/3/6 16:05
评论