2

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

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

代替

AND emp.pay_type = 'FT'

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

4

3 回答 3

4

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

NVL(exp1, val1)

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

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

如果条件为:

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

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

如果条件为:

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

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

于 2010-09-27T21:26:35.977 回答
3

我会用大量的盐来接受蟾蜍的“优化建议”。我称它们为优化的“霰弹枪”方法 - 向目标射击一大堆不同的位,看看其中一个以某种方式击中:)

无论如何,两者的区别

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

AND emp.pay_type = 'FT'

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

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

于 2010-09-28T04:57:56.960 回答
1

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

于 2010-09-27T21:47:13.883 回答