Oracle如何避免使用索引

如何避免使用索引
一般而言,人们更倾向于寻找一些方法,让成本优化器使用所创建的索引,而不是让它忽略现有的索引。不过,有些时候,你想要做的恰恰是:让优化器不使用索引。

1 在任何情况下都不使用某个索引
例如,在处理某个选择性不强的索引时,有可能希望不使用该索引。这是因为如果某个索引没有足够的选择性,扫描整个基础表有时会更有效。

如果SQL语句包含一个结构,如包括某个索引列的where子句,优化器可能会使用该列上的索引。为了阻止这种情况的发生,可以在查询语句中指定no_index提示,让优化器不得使用某个索引。例如:

SQL> select /*+ no_index(emp dept_idx) */ * from emp where department_id=10;


Execution Plan
----------------------------------------------------------
Plan hash value: 3956160932

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |    69 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| EMP  |     1 |    69 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("DEPARTMENT_ID"=10)

这个例子列出了想要让优化器忽略的具体索引。如果在表上有其他索引,优化器仍然会考虑使用那些索引。

除了指定单个索引,也可以列出一组优化器必须忽略的索引。如果只是指定no_index提示,而没有列出任何索引,优化器将忽略你指定的表的所有索引。与在本章后面将会介绍的index提示一样,no_index提示适用于B树索引,基于函数的索引,聚簇索引和域索引。

2 只避免快速扫描
no_index_ffs提示可以用来指示优化器避免对某个索引执行索引快速全扫描。请注意,与index提示的情况一样,必须在指定这个提示的同时指定特定的索引名字。例如:

SQL> select /*+ no_index_ffs(test test_i1) */   c from test;

同样,也可以使用no_index_ss提示来告诉优化器排队表中具体索引的跳跃式扫描。

3 强制表扫描
另一种避免使用索引的方法是从相反的方向解决问题,即明确要求执行表扫描。使用full提示指示优化器选择全表扫描而不是索引扫描。下面是如何指定full提示的例子:

SQL> select /*+ full(emp ) */ * from emp where department_id=10;

发表评论

电子邮件地址不会被公开。