前言
你是否有时会困惑:你刚创建的索引怎么不工作了?如果你正因此感到困惑的同时看到这篇文章,那么恭喜你,你的困惑即将被解决!我将常见的问题一一列出,并提供了解决办法,下面和我一起来看看你的困惑是哪种吧!
索引未被使用的可能原因(三)
是否使用了视图或子查询?
查询语句如果涉及到视图或者子查询时可能会被优化器等价改写,比如视图合并和谓词推入 ,导致不使用索引(改写目的之一是找到更多的访问路径从而选出效率最佳的方案)。重写一般来说都是合并(merge)操作。
是否访问了远端表 ?
通常远端表不会使用索引 。索引在分布式查询中的使用依赖于被发送到远程的查询。CBO将评估远程访问的成本,并评估比较发送或者不发送索引的谓词到远程站点的成本。因此,CBO 可以做出有关远端表上使用索引的更加明智的决定。一个非常有效的方法就是在远程建立包含相关谓词的视图并强制使用索引,之后在本地查询中使用这个视图。
是否使用并行执行 ?
在并行执行时索引的采用比在串行执行时更加严格。一个最简单的方法就是禁用并行,然后查看该索引是否被使用。所以 不要随便在SQL中开并行!
是否有关联更新?
关联更新是一种包含了子查询的update语句。在某些情况下,基于成本的考虑,索引没有被选使用是因为它依赖于一个子查询返回的值。这种情况下,可以使用HINT来强制使用索引。
查询是否使用了绑定变量?
CBO对like或范围谓词(如,between,>, <)的绑定变量不能判断出准确的成本COST。这可能会导致索引不被使用。
查询是否引用了带有延迟约束的列 ?
如果一个表中的某一列上含有延迟约束(如NOT NULL)并且这一列上有索引,那么不管这个约束当前是延迟状态或是被显式地设置为立即使用,我们都不会考虑使用这一列上的索引。如:
CREATE TABLE tab ( aaa INT CONSTRAINT aaa_not_null NOT NULL DEFERRABLE INITIALLY DEFERRED RELY, bbb INT CONSTRAINT bbb_not_null NOT NULL, ccc VARCHAR2(30) ); CREATE INDEX idx_aaa ON tab(aaa); SET CONSTRAINTS ALL IMMEDIATE; -- 将所有延迟约束设置为立即使用 SET AUTOTRACE TRACEONLY EXPLAIN SELECT COUNT(1) FROM tab; -- 索引不会被使用 Execution Plan ---------------------------------------------------------- Plan hash value: 56244968 ------------------------------------------------------------------- | Id | Operation | Name | Rows | Cost (%CPU)| Time | ------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 2 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | | | | 2 | TABLE ACCESS FULL| TDC | 1 | 2 (0)| 00:00:01 | -------------------------------------------------------------------
索引HINT是否未生效?
有关索引HINT的具体用法和详细功能,可以参考我的另外两个系列博文:
Oracle Hint之概念与用法: http://blog.itpub.net/69992972/viewspace-2756965/
Oracle Hint之常用Hint功能概述 : http://blog.itpub.net/69992972/viewspace-2757087/
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/69992972/viewspace-2766797/,如需转载,请注明出处,否则将追究法律责任。