10.3.4 基于函数的索引
基于函数的索引是将索引建立在某个函数或者某个表达式的基础上。在一些查询中,需要对某个列的值进行某种运算,在这种情况下,可以创建基于函数的索引。例如,考虑下面的查询:
SQL>SELECT*FROM emp WHERE lower(ename)='smith';
如果没有在表emp的ename列上创建索引,那么在执行这条语句时,需要把ename列的值转换成小写,然后与字符串“smith”进行比较。为了加快查询速度,可以在ename列上创建一个索引,先对该列上的值进行相应的转换,然后把转换后的值存储在索引中,这样在执行查询时就不需要再进行转化了。以下语句用来在表emp的ename列上创建基于函数lower的索引。
SQL>CREATE INDEX emp_idx2 ON emp(lower(ename));
索引所基于的函数可以是预定义函数,也可以是用户自定义的函数。无论是哪种情况,函数必须已经存在。例如,为了计算员工的个人所得税,在数据库中先创建一个用来计算员工个人所得税的函数,假设税率为3%。
CREATE OR REPLACE FUNCTION tax(sal IN emp.sal%type,
comm IN emp.comm%type)
RETURN NUMBER
DETERMINISTIC
IS
BEGIN
RETURN((sal+NVL(comm,0))*0.03);
END;
利用上面的函数,可以很方便地计算员工应该缴纳的个人所得税。假设经常要根据个人所得税查询员工的信息,可以在表emp上创建一个基于上述函数的索引:
SQL>CREATE INDEX emp_tax_indx
ON emp(tax(sal, comm));
那样以后在查询语句中就可以引用这个索引了,例如:
SQL>SELECT ename, sal, comm FROM emp
WHERE tax(sal, comm)>50
基于函数的索引还有另外一种形式,那就是用一个表达式代替函数。例如,个人所得税可以通过表达式(sal+nvl(comm,0))*0.03来计算,那么可以基于这个表达式在表emp上创建一个索引:
SQL>CREATE INDEX emp_idx3 ON emp((sal+nvl(comm,0))*0.03);
这个索引在以下形式的查询中将起作用:
SQL>SELECT ename, sal, comm FROM emp
WHERE(sal+nvl(comm,0))*0.03>50
需要注意的是,基于函数的索引并不是可以直接起作用的。在创建基于函数的索引之后,应该对表进行分析。例如:
SQL>ANALYZE TABLE emp COMPUTE STATISTICS;