函数索引在与其他运算符一起使用的 oracle 中不起作用

Function index does not work in oracle where it is used with other operator

您假设这个简单的查询:

select name, code 
  from item 
 where length(code) > 5

由于避免完全访问table,通过以下命令在长度(代码)上有一个函数索引:

create index index_len_code on item(length(code));

优化器检测索引并使用它(INDEX RANGE SCAN)。尽管如此,优化器并未检测到以下查询的上述索引:

select i.name, i.code
  from item i, item ii
 where length(i.code) - length(ii.code) > 0

当我看到执行计划时,是访问已满table,而不是索引范围扫描,而索引存在于length(code)上。

哪里不对,哪里不对?

如果您有一个 EMP table 和一个列 HIREDATE,并且该列被索引,那么优化器可能会选择使用索引来访问 table 在条件如

的查询中
... HIREDATE >= ADD_MONTHS(SYSDATE, -12)

查找过去 12 个月内雇用的员工。

但是,HIREDATE 必须 单独 在左侧。如果您向它添加或减去月或天,或者如果您将它包装在像 ADD_MONTHS 这样的函数调用中,则无法使用该索引。优化器不会执行简单的算术运算来将条件转换为 HIREDATE 本身必须满足不等式的条件。

您的第二个查询也发生了同样的情况。如果将条件更改为

... length(i.code) > length(ii.code)

然后优化器可以在 length(code) 上使用基于函数的索引。但即使在您的第一个查询中,如果您将条件更改为

... length(code) - 5 > 0

不会使用索引,因为这不是 length(code) 上的不等式条件。同样,优化器不够智能,无法执行琐碎的代数操作,无法以 length(code) 本身不等式条件的形式重写它。