NULL值常量替换

时间:2010-09-27 21:19:43

标签: sql oracle toad

为了好玩,我今天一直在玩Toad的内置Optimizer for Oracle。它建议的优化之一是以下

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

而不是

AND emp.pay_type = 'FT'

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

3 个答案:

答案 0 :(得分:4)

这是一个奇怪的建议。 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。

答案 1 :(得分:3)

我会用大量的盐来蟾蜍的“优化建议”。我把它们称为“霰弹枪”优化方法 - 在目标上射出很多不同的位,看看它们中的哪一个命中,不知何故:)

无论如何,

之间的区别
AND emp.pay_type = NVL('FT', UID)

AND emp.pay_type = 'FT'

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

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

答案 2 :(得分:1)

Oracle的解释计划告诉您有关这两个查询的内容是什么?