合 Oracle为何在查询中索引未被使用 (文档 ID 1549181.1)
- 简介
- 为何在查询中索引未被使用 (Doc ID 1549181.1)
- 快速检查
- 表上是否存在索引?
- 索引是否应该被使用?
- 索引本身的问题
- 索引列或者索引的前置列是否在单表(non-join)查询的 Where 条件中(predicate list)?
- 索引列是否用在连接谓词中(join predicates)?
- 索引列在 IN 或者多个 OR 语句中?
- 索引列是否被函数修改?
- 隐式类型转换(implicit type conversion)是什么?
- 是否在语义(semantically)上无法使用索引?
- 错误类型的索引扫描?
- 是否索引列为可空?
- NLS_SORT是否设置为二进制(BINARY)?
- 是否使用的是不可见索引(invisible indexes)?
- 优化器和成本计算相关问题
- 是否存在准确且合适的统计信息(Statistics)?
- 一个索引是否与其它的索引有相同的等级或者成本(cost)?
- 索引的选择度不高?
- 在总体成本中,表扫描的成本占大部分
- 访问空索引并不意味着比访问有值的索引高效。
- 参数设置
- 其它问题
- 是否使用了视图/子查询?
- 是否存在远程表(remote table)?
- 是否使用并行执行(PX)?
- 是否是包含了子查询的Update语句?
- 查询是否使用了绑定变量?
- 查询是否引用了带有延迟约束的列?
- 索引提示(hint)不工作
- 参考
简介
“为什么索引没有被使用”是一个涉及面较广的问题。有多种原因会导致索引不能被使用。首要的原因就是统计信息不准,第二原因就是索引的选择度不高,使用索引比使用全表扫描效率更差。还有一个比较常见的原因,就是对索引列进行了函数、算术运算或其他表达式等操作,或出现隐式类型转换,导致无法使用索引。还有很多其它原因会导致不能使用索引,这个问题在MOS(MOS即My Oracle Support)“文档1549181.1为何在查询中索引未被使用”中有非常详细的解释上了。
下面是一些非常有用的检查项目。
一、快速检查
表上是否存在索引?
索引是否应该被使用?
二、索引本身的问题
索引的索引列是否在WHERE条件中(Predicate List)?
索引列是否用在连接谓词中(Join Predicates)?
连接顺序(Join Order)是否允许使用索引?
索引列是否在IN或者多个OR语句中?
是否对索引列进行了函数、算术运算或其他表达式等操作?
索引列是否出现了隐式类型转换(Implicit Type Conversion)?
是否在语义(Semantically)上无法使用索引?
错误类型的索引扫描?
索引列是否可以为空?
NLS_SORT是否设置为二进制(BINARY)?
是否使用的是不可见索引(Invisible Indexes)?
三、优化器和成本计算相关问题
是否存在准确且合适的统计信息(Statistics)?
一个索引是否与其它的索引有相同的等级或者成本(Cost)?
索引的选择度是否不高?
在总体成本中,表扫描的成本是否占大部分?
访问空索引并不意味着比访问有值的索引高效?
参数设置是否正确?
四、其它问题
是否存在远程表(Remote Table)?
是否使用了并行执行(PX)?
是否包含了子查询的UPDATE语句?
查询是否使用了绑定变量?
查询是否引用了带有延迟约束的列?
本人提供Oracle(OCP、OCM)、MySQL(OCP)、PostgreSQL(PGCA、PGCE、PGCM)等数据库的培训和考证业务,私聊QQ646634621或微信db_bao,谢谢!