【发布时间】:2016-01-06 03:37:40
【问题描述】:
请在标记为重复之前阅读最后几段。
在 Oracle 9i 数据库中,此查询在 0.18 秒内运行:
select
count(*)
from
dba_synonyms s,dba_objects t
where
s.TABLE_OWNER = t.OWNER(+) and
s.TABLE_NAME = t.OBJECT_NAME(+) and
s.DB_LINK is null and
t.OWNER is null;
...但是这个运行在一个可怕的 120 秒!:
select
count(*)
from
dba_synonyms s left join dba_objects t
on ( s.TABLE_OWNER = t.OWNER and s.TABLE_NAME = t.OBJECT_NAME )
where
s.DB_LINK is null and
t.OWNER is null;
请注意,唯一的区别是使用专有的 Oracle 连接语法与 ANSI 连接语法。
这些问题不是this one 的重复问题,因为另一个问题是关于涉及超过 9 个表的非常复杂的查询,唯一的答案指出除了语法用法(主要是表的顺序)。
在我的例子中,它是一个非常简单的查询,只是两个关系之间的连接,没有主要的差异并发症,包括表的顺序。
- 这是 Oracle 9i 中的错误吗?
- 造成如此巨大的性能差异的原因是什么?
更新:
这是执行计划,注意查询一的解释计划没有显示基数、成本或字节信息:
【问题讨论】:
-
由于不再支持 Oracle 9i,因此很难确定是什么导致了性能问题。您是否尝试过比较他们的解释计划?
-
@Sentinel 执行计划大相径庭,但它们不应该如此,因为在两个查询中我只是进行简单的连接。没有更改表顺序,没有对任何列应用函数,WHERE 子句中没有引入新条件,选择的列相同,等等。我猜 Ora9i 只是以一种疯狂的方式解析 ANSI 版本,导致一种执行计划,不仅与旧式查询不同,而且效率非常低。
-
@Sentinel 我在问题中添加了每个查询的解释计划,请看一下。也许你可以向我解释为什么第二个这么慢,最重要的是,为什么 Ora9i 选择了如此糟糕的执行计划而不是另一个。
-
"这是 Oracle 9i 中的错误吗?" - 我记得 Oracle 9 中的显式 JOIN 语法存在大量问题,Oracle 10 中仍然存在一些问题(可能Oracle 社区对显式 JOIN 的接受度很低的原因之一)。不过,我从未在 11g 或 12c 中看到过问题
-
刚刚测试了 10g 和 11g 中的查询,两个版本都在
标签: performance join syntax oracle9i ansi-sql