您假设这个简单的查询:
select name, code
from item
where length(code) > 5
由于避免了完全访问表,因此通过以下命令有一个函数索引长度(代码):
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
当我看到执行计划时,它是访问全表,而不是索引范围扫描,而索引存在于长度(代码)上。
错在哪里,哪里出错了?
如果你有一个带有EMP
列的HIREDATE
表,并且该列被索引,那么优化器可以选择使用索引来访问具有类似条件的查询中的表
... 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)
本身的不等式条件。