您可以基于函数、或涉及相关表的一个或多个列的表达式来创建索引。基于函数的索引计算函数或涉及一个或多个列的表达式的值,并将其存储在索引中。基于函数的索引可以是一个B-树索引或位图索引。
用于生成索引的函数可以是算术表达式,或一个包含SQL函数、用户定义PL/SQL函数、包函数,或C调用的表达式。例如,函数可以将两个列中的值相加。
使用基于函数的索引
基于函数的索引对于在WHERE子句中包含函数计算的语句是有效的。仅当在查询中包含该函数时,数据库才使用基于函数的索引。当数据库处理INSERT和UPDATE语句时,它仍然必须计算函数才能完成对语句的处理。
例如,假设您创建如下基于函数的索引:

当数据库处理如示例3-6(包括部分示例输出)所示的查询时,它可以使用前面定义的索引。
示例3-6包含算术表达式的查询

基于SQL函数UPPER(column_name)或LOWER(column_name)定义的索引,使对大小写无关的搜索变得非常方便。例如,假设雇员表的first_name列包含混合大小写字符。您在hr.employees表上创建了如下基于函数的索引:

基于函数的索引对于只在一个表中的特定行上建立索引也是有用的。例如sh.customers表中的cust_valid列有I或A两个值。如果只想对含A值的行建立索引,您可以编写一个函数,让不含A值的其它任何行都返回一个空值。可以这样创建索引,如下所示:

优化基于函数的索引
对于在WHERE子句中包含表达式的查询,优化程序可以在一个基于函数的索引上使用索引范围扫描。当谓词(WHERE子句)的选择性很低时,范围扫描的访问路径显得特别有优势。示例3-6中,如果索引是基于表达式12salarycommission_pct来创建的,则优化程序可以使用索引范围扫描。
虚拟列可用于快速访问由表达式生成的数据。例如,您可以为表达式12salarycommission_pct定义虚拟列annual_sal,并在该annual_sal列上创建一个基于函数的索引。
优化程序通过分析在SQL语句中的表达式来执行表达式匹配,然后比较的语句表达式目录树和基于函数的索引。这种比较不区分大小写,并忽略空格。




