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

函数索引在与其他运算符一起使用的oracle中不起作用,oracle,indexing,query-performance,Oracle,Indexing,Query Performance,假设这个简单的查询: select name, code from item where length(code) > 5 由于避免了完全访问表,通过以下命令在长度(代码)上有一个函数索引: create index index_len_code on item(length(code)); 优化器检测索引并使用它(索引范围扫描)。尽管如此,优化器不会检测以下查询的上述索引: select i.name, i.code from item i, item ii wher

假设这个简单的查询:

select name, code 
  from item 
 where length(code) > 5
由于避免了完全访问表,通过以下命令在长度(代码)上有一个函数索引:

create index index_len_code on item(length(code));
优化器检测索引并使用它(索引范围扫描)。尽管如此,优化器不会检测以下查询的上述索引:

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\u months
,则无法使用索引。优化器不会执行琐碎的算术操作,以将条件转换为
HIREDATE
本身必须满足不等式的条件

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

... length(i.code) > length(ii.code)
... length(code) - 5 > 0
然后优化器可以使用基于
长度(code)
的函数索引。但即使在第一次查询中,如果将条件更改为

... length(i.code) > length(ii.code)
... length(code) - 5 > 0

不会使用索引,因为这不是
length(code)
上的不等式条件。同样,优化器也不够聪明,无法执行琐碎的代数操作,以将其重写为
长度(code)
本身的不等式条件。

如果您有一个
EMP
表,其中有一列
HIREDATE
,并且该列被索引,然后优化器可以选择使用索引来访问查询中的表,条件如下

... HIREDATE >= ADD_MONTHS(SYSDATE, -12)
寻找过去12个月雇佣的员工

但是,左侧的
HIREDATE
必须是单独的。如果向其添加或减去月份或天数,或者将其包装在函数调用中,如
add\u months
,则无法使用索引。优化器不会执行琐碎的算术操作,以将条件转换为
HIREDATE
本身必须满足不等式的条件

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

... length(i.code) > length(ii.code)
... length(code) - 5 > 0
然后优化器可以使用基于
长度(code)
的函数索引。但即使在第一次查询中,如果将条件更改为

... length(i.code) > length(ii.code)
... length(code) - 5 > 0

不会使用索引,因为这不是
length(code)
上的不等式条件。同样,优化器也不够聪明,无法执行琐碎的代数操作,从而将其重写为
length(code)
本身的不等式条件。

索引对第二个查询有何帮助?将条件重写为
length(i.code)>length(ii.code)
;优化器可以(也可以不)选择使用索引。您要求优化器执行像这样的琐碎代数操作,但它不能-这样做太愚蠢了。@Mat-优化器可以选择执行索引范围扫描作为访问方法。索引中的值已排序;如果聚类因子很高,优化器可能会认为这样的策略是有益的。为了进一步澄清我的评论:在第一个简单的查询中,如果您将条件重写为
length(code)-5>0
,FBI将不会被使用,原因与此相同。@mathguy什么是FBI。我是新来的!!!!索引对您的第二次查询有何帮助?将条件重写为
length(i.code)>length(ii.code)
;优化器可以(也可以不)选择使用索引。您要求优化器执行像这样的琐碎代数操作,但它不能-这样做太愚蠢了。@Mat-优化器可以选择执行索引范围扫描作为访问方法。索引中的值已排序;如果聚类因子很高,优化器可能会认为这样的策略是有益的。为了进一步澄清我的评论:在第一个简单的查询中,如果您将条件重写为
length(code)-5>0
,FBI将不会被使用,原因与此相同。@mathguy什么是FBI。我是新来的!!!!如果我必须使用'length(code)-5',应用索引范围扫描的解决方案是什么?我的意思是克服此限制的解决方案是什么?@rezaramezanimatin-如果出于某种原因必须使用
length(code)-5
(并且不能将5移到另一侧),则基于函数的索引不应位于
length(code)上
,但它应该在
长度(code)-5上。如果我必须使用“长度(code)-5”,应用索引范围扫描的解决方案是什么?我的意思是克服此限制的解决方案是什么?@rezaramezanimatin-如果出于某种原因必须使用
长度(code)-5
,然后,基于函数的索引不应位于
length(code)
,而应位于
length(code)-5