Oracle为何在查询中索引未被使用 (文档 ID 1549181.1)

0    300    2

Tags:

👉 本文共约9486个字,系统预计阅读时间或需36分钟。

简介

“为什么索引没有被使用”是一个涉及面较广的问题。有多种原因会导致索引不能被使用。首要的原因就是统计信息不准,第二原因就是索引的选择度不高,使用索引比使用全表扫描效率更差。还有一个比较常见的原因,就是对索引列进行了函数、算术运算或其他表达式等操作,或出现隐式类型转换,导致无法使用索引。还有很多其它原因会导致不能使用索引,这个问题在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语句?

  • 查询是否使用了绑定变量?

  • 查询是否引用了带有延迟约束的列?

  • 索引提示(Hint)是否不工作?

  • 索引列是否使用了前置通配符(%)?

  • 索引列是否使用了非等值连接符?

  • 是否在WHERE子句中对索引列进行了IS NULL值判断?

  • 是否查询转换失败导致不能选择索引?

  • 是否使用了视图或子查询?

img

img

为何在查询中索引未被使用 (Doc ID 1549181.1)

“为什么索引没有被使用”是一个涉及面较广的问题。有很多种原因会导致索引没有被使用。下面是一些非常有用的检查列表。请点击下面链接来查看文章的具体内容:

快速检查

  • 表上是否存在索引?

    检查您认为应该通过索引访问的表上是否真的有定义索引。那些索引可能已经被删掉或者在创建的时候就失败了 – 比如一种可能的场景是,在对表做导入或 load 操作后,由于软件或人为错误造成索引没有被创建。下面的语句可以用来检查索引是否存在。

  • 索引是否应该被使用?

    Oracle 不会仅仅因为有索引存在就一定要使用索引。如果一个查询需要检索出这个表里所有的记录(比如说表之间做连接操作),那为什么还要既访问索引的所有数据又访问表的所有数据呢?在这种情况下只访问表的数据会更快。对所有的查询 Oracle Optimizer 会基于统计信息来计算各种访问路径,包括索引,从而选出最优的一个。

索引本身的问题

标签:

Avatar photo

小麦苗

学习或考证,均可联系麦老师,请加微信db_bao或QQ646634621

您可能还喜欢...

发表回复