使用索引的误区之二:使用了 和 != 操作符,导致查询不使用索引
2009-01-13 16:12
621 查看
使用索引的误区之二:使用了 <> 和 != 操作符,导致查询不使用索引
http://blog.csdn.net/lunar2000/archive/2004/11/24/193475.aspx
首先,请记住这个结论:[/b]
使用了<> 和!=后,就不会使用索引[/b][/b]
例如,下面的例子使用了<>,所以查询没有用到索引[/b]
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
[/b]
将上面的查条件“empno <>10”转换成“empno <10 and empno>10”后,就可以使用索引了[/b]
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>
再看下面的例子:[/b]
由于使用了前导列,所以使用了索引,后面的"!="是从索引范围扫描的结果中筛选合适的记录的[/b]
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
再做一个试验:[/b]
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
如果使用"<>",则查询不使用索引:[/b]
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'”,则可以使用索引[/b]
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>
评论#piner 发表于2005-01-20 17:15:00 IP: 218.108.88.*首先,请记住这个结论: 使用了<> 和!=后,就不会使用索引 ????? 这个结论不正确,有误导倾向 #lunar 发表于2005-03-01 16:38:00 IP: 218.249.251.* 是有些问题,或许应该改成,如果使用了<> 和 !=操作,如果不用提示的话,系统就不用索引,这样应该可以了吧,呵呵。 #ccq 发表于2006-03-23 21:17:00 IP: 172.17.35.* select empno from emp where empno <>10; 等价于: select empno from emp where empno <10 and empno>10; 不会吧? 是否可以调整为: select empno from emp where empno <10 union all select empno from emp where empno >10; #lunar 发表于2006-03-24 08:21:00 IP: 218.206.69.* 对,粗心了,不好意思 :) |
相关文章推荐
- 使用索引的误区之二:使用了 和 != 操作符,导致查询不使用索引
- 使用索引的误区之二:使用了和!=操作符,导致查询不使用索引
- 使用索引的误区之二:使用了 和 != 操作符,导致查询不使用索引
- 使用索引的误区之二:使用了 和 != 操作符,导致查询不使用索引
- 使用索引的误区之一:没有使用复合索引的前导列导致查询不使用索引
- 使用索引的误区之一:没有使用复合索引的前导列导致查询不使用索引
- 使用索引的误区之一:没有使用复合索引的前导列导致查询不使用索引
- 使用索引的误区之一:没有使用复合索引的前导列导致查询不使用索引
- 使用索引的误区之一:没有使用复合索引的前导列导致查询不使用索引
- 使用索引的误区之一:没有使用复合索引的前导列导致查询不使用索引——oracle
- Mysql多个LEFT JOIN使用ORDER不能使用索引导致查询过慢的解决方案
- 错误使用MySQL前缀索引导致的慢查询
- Mysql多个LEFT JOIN使用ORDER BY不能使用索引导致查询过慢的解决方案
- Mysql多个LEFT JOIN使用ORDER不能使用索引导致查询过慢的解决方案
- PosgreSQL 索引 COLLATE 设置不当导致查询优化无法使用索引
- PosgreSQL 索引 COLLATE 设置不当导致查询优化无法使用索引
- mysql查询索引使用情况
- 测试mysql查询中参数整形和字符串类型错误索引使用情况
- 使用索引来排序查询结果
- 限制索引导致索引无法被使用