首先我们要知道的一点就是CBO的代码oracle是不会对我们公开的,起码现在是。所以本文中的结论不一定适用所有的版本。在应用本文的结论之前最好先试一下。
ok 下面就是本文的结论,当你在where语句中使用不等于或者not in时候,oracle 倾向于忽略索引。 比如:
SQL> Select * from test where text<>‘star‘;
IDTEXT
---------- ------------
4939426 sun
这条语句即使在test上有索引,oracle也仍然会忽略。
接下来我们分析证明一下这是为什么。 其实,我认为oracle这么做是有道理的。一般我们在写SQL的时候,如果用了
<>,也就是不等于,通常都是说选取结果集中的很大一部分。我们可以感受一下平时我们的思维方式和和习惯确实是这样的。比如我们说要"找出这些人中不是姓李的","找出这些车中不是大众的"。这一般来说是要返回结果集中很大一部分的。Oracle认为如果是这样,那么用索引不如全表扫描迅速,所以这种情况根本就不考虑索引,直接采用全表扫描。
而且oracle认为,如果你知道你的<>会返回少量的结果,那么你应该会调整你的SQL 用 (< or >)来代替。
下面我们验证一下。
首先创建表。一个很大的表。
SQL> select * fromv$version;
BANNER--------------------------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 -64bi
PL/SQL Release 10.2.0.5.0 -Production
CORE10.2.0.5.0Production
TNSfor Solaris: Version 10.2.0.5.0 -Production