4

我有一个应该返回 2 行的查询。但是,它返回 48 行。它的行为就像正在连接的表之一不存在。但是,如果我将该表中的一列添加到 select 子句,而不更改查询的 from 或 where 部分,它将返回 2 行。

以下是“解释计划”在选择中没有“m.*”时所说的内容: 先解释计划

在选择中添加 m.* 后再次出现这里: 解释计划后

谁能解释为什么它应该这样表现?

更新:我们只在一个系统上遇到过这个问题,而在另一个系统上没有。DBA 验证了有问题的运行 optimizer_features_enable 设置为 10.2.0.5,而没有发生问题的运行 optimizer_features_enable 设置为 10.2.0.4。不幸的是,客户站点正在运行 10.2.0.5。

4

2 回答 2

2

这是关于 10gR2 中引入的连接消除:

表消除(也称为“连接消除”)从查询中删除冗余表。如果表的列仅在连接谓词中被引用,则表是冗余的,并且可以保证这些连接既不过滤也不扩展结果行。在几种情况下,Oracle 会消除冗余表。

也许这是一种相关的错误。看看这篇文章。

于 2011-03-15T06:03:43.913 回答
0

看起来像一个错误。有什么限制?

从逻辑上讲,如果 MASTERSOURCE_FUNCTION 中的所有行都具有函数 NON-OSDA 则不会排除任何行(或者如果没有任何行具有该值,则将排除所有行)。

更进一步,如果 MASTERSOURCE 中的每一行在 MASTERSOURCE_FUNCTION 中都有一个或零个 NON-OSDA 行,那么它应该是排除的候选对象。但 MASTERSOURCE ID 和 NAME 之间也需要一对一的关系。

我将从 ACCOUNTSOURCE 中提取 48 行的 ROWID,然后跟踪 MASTERSOURCE ID 和 NAME 并查看这些行被复制或不排除的原因。也就是说,在 MASTERSOURCE 中是否有 12 个重复的名称,通过 NOVALIDATE 约束预计它是唯一的。

于 2011-03-15T11:57:01.880 回答