【问题标题】:NVL faster than is not null condition?NVL 比非空条件快吗?
【发布时间】: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 函数更快?

标签: sql oracle oracle11g


【解决方案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 是更简单、更清晰的条件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-14
    • 2014-12-30
    • 2011-06-16
    • 2017-11-14
    • 2012-05-03
    • 2021-09-15
    • 2011-01-09
    相关资源
    最近更新 更多