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

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

http://blog.csdn.net/lunar2000/archive/2004/11/24/193475.aspx

首先,请记住这个结论:<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

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

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

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 <><?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><chmetcnv w:st="on" unitname="”" sourcevalue="10" hasspace="False" negative="False" numbertype="1" tcsc="0">10<span lang="EN-US"><span lang="EN-US">”</span></span></chmetcnv>转换成“empno <10 and empno><chmetcnv w:st="on" unitname="”" sourcevalue="10" hasspace="False" negative="False" numbertype="1" tcsc="0">10<span lang="EN-US"><span lang="EN-US">”</span></span></chmetcnv>后,就可以使用索引了

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>

评论

# piner发表于2005-01-20 17:15:00IP: 218.108.88.*
首先,请记住这个结论:

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

这个结论不正确,有误导倾向
# lunar发表于2005-03-01 16:38:00IP: 218.249.251.*
是有些问题, 或许应该改成,如果使用了<> 和 !=操作,如果不用提示的话,系统就不用索引,这样应该可以了吧,呵呵。
# ccq发表于2006-03-23 21:17:00IP: 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:00IP: 218.206.69.*
对,粗心了,不好意思 :)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值