在 SQL 语句中使用 NULL 会有很多的麻烦。因此建议开发人员在建表时,把需要索引的列
设成NOTNULL。如果被索引的列在某些行中存在 NULL 值,就不会使用这个索引(除非
索引是一个位图索引,关于位图索引在稍后在详细讨论)。
1.6.3使用函数
如果不使用基于函数的索引,那么在 SQL 语句的 WHERE 子句中对存在索引的列使用函
数时,会使优化器忽略掉这些索引。下面的查询不会使用索引(只要它不是基于函数的索
引)
selectempno,ename,deptnofromempwheretrunc(hiredate)='01-MAY-81';
把上面的语句改成下面的语句,这样就可以通过索引进行查找。
selectempno,ename,deptnofromempwherehiredate<(to_date('01-MAY-81')+0.9999);
1.6.4比较不匹配的数据类型
也是比较难于发现的性能问题之一。注意下面查询的例子,account_number 是一个
VARCHAR2 类型,在 account_number 字段上有索引。
下面的语句将执行全表扫描:
selectbank_name,address,city,state,zipfrombankswhereaccount_number=990354;
Oracle 可以自动把 where 子句变成 to_number(account_number)=990354,这样就限制
了索引的使用,改成下面的查询就可以使用索引:
selectbank_name,address,city,state,zipfrombankswhereaccount_number='990354';
特别注意:不匹配的数据类型之间比较会让 Oracle 自动限制索引的使用,即便对这个
查询执行 ExplainPlan 也不能让您明白为什么做了一次“全表扫描”。
1.7查询索引
查询 DBA_INDEXES 视图可得到表中所有索引的列表,注意只能通过 USER_INDEXES 的
方法来检索模式(schema)的索引。访问 USER_IND_COLUMNS 视图可得到一个给定表中
被索引的特定列。
1.8组合索引
当某个索引包含有多个已索引的列时,称这个索引为组合(concatented)索引。在Oracl
e9i 引入跳跃式扫描的索引访问方法之前,查询只能在有限条件下使用该索引。比如:表
emp 有一个组合索引键,该索引包含了 empno、ename 和 deptno。在 Oracle9i 之前除非
在 where 之句中对第一列(empno)指定一个值,否则就不能使用这个索引键进行一次范
围扫描。
特别注意:在 Oracle9i 之前,只有在使用到索引的前导索引时才可以使用组合索引!
1.9ORACLEROWID
通过每个行的 ROWID,索引 Oracle 提供了访问单行数据的能力。ROWID 其实就是直接
指向单独行的线路图。如果想检查重复值或是其他对 ROWID 本身的引用,可以在任何表
中使用和指定 rowid 列。
1.10选择性
使用 USER_INDEXES 视图,该视图中显示了一个 distinct_keys 列。比较一下唯一键的
数量和表中的行数,就可以判断索引的选择性。选择性越高,索引返回的数据就越少。