NVL 比非空条件快吗?

Posted

技术标签:

【中文标题】NVL 比非空条件快吗?【英文标题】:NVL faster than is not null condition? 【发布时间】:2015-08-19 13:35:09 【问题描述】:

我问自己 NVL 函数是否比 where is not null 条件更快。我在谷歌上搜索是否有人谈论它,但没有找到明确回答这个问题的人。

所以这是我有一个 sql 请求的情况,我想知道哪个更快。 在此示例中,我简化了我的查询,只是为了让您了解我想知道的内容。

这是带有 nvl 功能的请求

SELECT TA.MNT FROM TABLEA TA WHERE TA.ID NOT IN(SELECT NVL(TB.ID,-1) FROM TABLEB TB);

这是不为空的条件

SELECT TA.MNT FROM TABLEA TA WHERE TA.ID NOT IN(SELECT TB.ID FROM TABLEB TB WHERE TB.ID IS NOT NULL);

那么哪一个会更快返回?

【问题讨论】:

是否有某些原因您不能自己运行测试并确定答案..? 不,我只是想知道是否有可能一个比另一个快,或者一个总是比另一个快。 我试过了,似乎非空条件更快,但我想知道 NVL 函数是否有某种方法可以更快。 如果 tb.id 上有索引,我会假设第二个查询可以使用它,而第一个查询不太可能使用它。不过,这完全取决于您的表和数据的结构。不过,我倾向于使用第二个查询,因为它更容易理解。 为什么希望 NVL 函数更快? 【参考方案1】:

它们的逻辑不同。

考虑在TABLEB 中以NULL, 0, 1 开头。 - NVL 版本将其更改为 -1, 0, 1 - WHERE IS NOT NULL 将其更改为 0, 1

这意味着NOT INWHERE NOT NULL 中检查的项目更少,这就是它可以更快的原因。

也就是说,使用NOT IN 通常不是最快的。两个标准选项是LEFT JOINNOT EXISTS

SELECT
  TABLEA.*
FROM
  TABLEA
LEFT JOIN
  TABLEB
    ON TABLEB.ID = TABLEA.ID
WHERE
  TABLEB.ID IS NULL

SELECT
  TABLEA.*
FROM
  TABLEA
WHERE
  NOT EXISTS (SELECT *
                FROM TABLEB
               WHERE TABLEB.ID = TABLEA.ID
             )

【讨论】:

如果id 可以是-1,可能还需要注意区别。那么,这两种形式是非常非常不同的。我还认为where 表单可以以nvl() 表单无法利用的方式利用索引。 id 不能是 -1 这就是我使用它的原因。【参考方案2】:

我做了一个与原始查询非常相似的基准测试,在这种情况下 NVL 慢了大约 47%。但与之前的 cmet 在实际应用中一致,它取决于很多方面,IS NULL 是更简单、更清晰的条件。

【讨论】:

以上是关于NVL 比非空条件快吗?的主要内容,如果未能解决你的问题,请参考以下文章

Oracle中nvl函数的用法和作用是啥?

Oracle系列:(11)通用函数和条件判断函数

Oracle:两个条件都为真时的条件非空约束

Sql 条件非空约束

JSF非空条件[重复]

如何在 YII2 中使用非空条件