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,是不是可以修改查询的主要内容,如果未能解决你的问题,请参考以下文章

MySQL中是不是有相当于Oracle的NVL的功能?

安卓 SQLITE FTS 版本

在oracle数据库中nvl()是啥函数?

JavaScript中是不是有类似forEach的函数,但它只返回索引,而不是对象和索引[关闭]

在数据库表级别而不是函数上进行约束

在oracle数据库中nvl()是啥函数?