【问题标题】:NULL Value Substitution on constant常量上的 NULL 值替换
【发布时间】:2010-09-27 21:19:43
【问题描述】:

为了好玩,我今天在 Toad 中使用内置的 Optimizer for Oracle。它建议的优化之一如下

AND emp.pay_type = NVL('FT', UID)

代替

AND emp.pay_type = 'FT'

我对这里发生的事情以及因此而感到困惑,也对为什么这会提高性能感到困惑。由于 FT 是 SQL 查询中的字符串文字,因此永远不会为 NULL,为什么这会有什么不同呢?我猜这与该领域的现有索引有关,但在 Oracle 文档中找不到任何内容。

【问题讨论】:

  • 无论 ut 是否提高性能,"AND emp.pay_type = NVL('FT', UID)" 和 "AND emp.pay_type = 'FT' 给出相同的结果。为什么使用 NVL在文字字符串上?

标签: sql oracle toad


【解决方案1】:

这是一个奇怪的建议。 NVL 函数的工作原理如下:

NVL(exp1, val1)

如果'exp1'不为null,则返回;否则返回 'val1'。

由于示例中的 'FT' 不能为 NULL,因此使用 NVL 函数没有任何好处,并且性能损失很小(至少对于优化器来说,NVL 是多余的;如果优化器可能会导致执行损失不知道 NVL 是多余的)。

如果条件为:

AND emp.pay_type = NVL("FT", UID)

那么可能会有好处;这里我们有一个分隔标识符(用双引号括起来的列名),列值可能是 NULL; NVL 调用确保仅当“FT”为 NULL 并且 UID 为 NULL 时才返回 NULL。当然,UID 是一个常规标识符。

如果条件为:

AND emp.pay_type = NVL(UID, 'FT')

现在如果 UID 值为 NULL,则使用默认值 'FT' 作为对应的 pay_type。

【解决方案2】:

我对蟾蜍的“优化建议”持怀疑态度。我称它们为优化的“霰弹枪”方法 - 向目标射击一大堆不同的位,看看其中一个以某种方式击中:)

不管怎样,两者的区别

AND emp.pay_type = NVL('FT', UID)

AND emp.pay_type = 'FT'

在第二种情况下,优化器可能会使用列上的直方图统计信息(如果它们已被收集)来获得对匹配行数的更准确估计。但是,当使用 NVL 时,优化器(我相信)不会检测到它可以忽略 NVL,因此不会检查直方图的值。

这不是我通常会使用的优化方法。有更好的方法来控制查询的执行路径(例如提示)。特别是,如果他们改进 CBO 以查找和优化像 NVL([literal value],[anything])[literal value] 这样的冗余代码,此方法将失败。

【讨论】:

    【解决方案3】:

    关于这两个查询,Oracle 的解释计划告诉您什么?

    【讨论】:

      猜你喜欢
      • 2021-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-12
      相关资源
      最近更新 更多