NVL函数不使用索引而不是FTS,是不是可以修改查询
Posted
技术标签:
【中文标题】NVL函数不使用索引而不是FTS,是不是可以修改查询【英文标题】:NVL function not using index rather FTS, is it possible to modify the queryNVL函数不使用索引而不是FTS,是否可以修改查询 【发布时间】:2020-07-01 18:05:51 【问题描述】:我的查询如下所示
select nvl(a.value1,nvl(b.value1,nvl(c.value1,''))
from table1 a, table2 b table3 c
where a.value2=b.value2 and b.value3=c.value3
由于此查询包含一个 nvl 函数,它从我的三个表中列出 value1,它正在进行全表扫描,我知道我是否可以创建基于函数的索引 oracle 应该考虑该索引,但我担心的是 nvl函数在三个不同表的列上我无法创建基于函数的索引,任何其他方式来重写查询或任何其他方式我可以在这里使用索引,请帮助
【问题讨论】:
您确定是 nvl 导致了您的问题 - 您没有在连接条件下使用它,因此 index/FTS 受到影响似乎很奇怪?顺便说一句,nvl(c.value1,'')
毫无意义,因为''
与 Oracle 中的 null 相同;你应该考虑使用现代连接语法。
【参考方案1】:
您可以使用coalesce
函数如下:
Coalesce(a.value1, b.value1, c.value1)
或者你可以使用case when
语句如下:
Case when a.value1 is not null then a.valie1
When b.value1 is not null then b.value1
Else c.value1
End
注意:coalesce
的性能优于NVL
,因为coleasce
使用短路评估意味着它仅在需要时评估参数。
【讨论】:
【参考方案2】:在没有查看执行计划的情况下,实际上不可能对查询做出明确的评论。我认为您不能同时在多个表上创建基于函数的索引。老实说,我怀疑 NVL 是一个很大的瓶颈。你可以做的是创建三个索引:
create index idx1 on table1( value2, value1 );
create index idx2 on table2( value3, value2, value1 );
create index idx3 on table3( value3, value1 );
至少,Oracle 不必为每个表获取完整的行。
【讨论】:
谢谢,我会试试的以上是关于NVL函数不使用索引而不是FTS,是不是可以修改查询的主要内容,如果未能解决你的问题,请参考以下文章