使用索引的误区之二:使用了 和 != 操作符,导致查询不使用索引

使用索引的误区之二:使用了 <> 和 != 操作符,导致查询不使用索引

** 首先,请记住这个结论: **

** 使用了 <> 和 != 后,就不会使用索引 **


** 例如,下面的例子使用了 <> ,所以查询没有用到索引 **

select empno from emp where empno <>10;

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

--------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost |

--------------------------------------------------------------------

| 0 | SELECT STATEMENT | | | | |

|* 1 | TABLE ACCESS FULL | EMP | | | |

--------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

1 - filter("EMP"."EMPNO"<>10)

Note: rule based optimization

14 rows selected


** 将上面的查条件“ empno <> 10 ” 转换成“empno <10 and empno> 10 ” 后,就可以使用索引了 **

select empno from emp where empno <10 and empno>10;

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

--------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost |

--------------------------------------------------------------------

| 0 | SELECT STATEMENT | | | | |

|* 1 | INDEX RANGE SCAN | EMP_ID1 | | | |

--------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

1 - access("EMP"."EMPNO">10 AND "EMP"."EMPNO"<10)

Note: rule based optimization

14 rows selected

SQL>

** 再看下面的例子: **

** 由于使用了前导列,所以使用了索引,后面的 "!=" 是从索引范围扫描的结果中筛选合适的记录的 **

select empno from emp where empno <=10 and ename != 'RICH';

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

--------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost |

--------------------------------------------------------------------

| 0 | SELECT STATEMENT | | | | |

|* 1 | INDEX RANGE SCAN | EMP_ID1 | | | |

--------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

1 - access("EMP"."EMPNO"<=10)

filter("EMP"."EMPNO"<=10 AND "EMP"."ENAME"<>'RICH')

Note: rule based optimization

15 rows selected

** 再做一个试验: **

SQL> desc dept

Name Type Nullable Default Comments

------ ------------ -------- ------- --------

DEPTNO NUMBER(2) Y

DNAME VARCHAR2(14) Y

LOC VARCHAR2(13) Y

创建一个单键索引:

SQL> create index dept_id1 on dept(dname);

Index created

** 如果使用 "<>" ,则查询不使用索引: **

select depTno from dept where dname <> 'DEVELOPER';

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

--------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost |

--------------------------------------------------------------------

| 0 | SELECT STATEMENT | | | | |

|* 1 | TABLE ACCESS FULL | DEPT | | | |

--------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

1 - filter("DEPT"."DNAME"<>'DEVELOPER')

Note: rule based optimization

14 rows selected

** 将条件修改为“ dname <'DEVELOPER' and dname>'DEVELOPER' ”,则可以使用索引 **

select deptno from dept where dname <'DEVELOPER' and dname>'DEVELOPER';

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

---------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost |

---------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | | | |

| 1 | TABLE ACCESS BY INDEX ROWID| DEPT | | | |

|* 2 | INDEX RANGE SCAN | DEPT_ID1 | | | |

---------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

2 - access("DEPT"."DNAME">'DEVELOPER' AND "DEPT"."DNAME"<'DEVELOPER')

Note: rule based optimization

15 rows selected

SQL>

Published At
Categories with 数据库类
comments powered by Disqus