【发布时间】:2014-11-23 19:34:21
【问题描述】:
我有一个 Web 应用程序,它使用一个非常复杂的数据库视图来检索一些看起来很慢的数据,最多只需要 3 分钟即可完成。经过彻底调查,我发现了问题的原因。 在我的代码中,我在 WHERE 子句中使用以下条件来仅检索连接表的最后一个元素:
SELECT ...
FROM MY_TABLE
JOIN TABLE_JOIN_XX tableA on ....
..lots of other joins ...
WHERE
tableA.id =
(SELECT MAX (id) FROM TABLE_JOIN_XX tableB WHERE tableA.id_parent = tableB.id_parent)
然后我通过以下方式更改了条件:
tableA.id >= ALL
(SELECT id FROM TABLE_JOIN_XX tableB WHERE tableA.id_parent = tableB.id_parent)
现在查询只需要几秒钟。
现在我想知道为什么使用 MAX 运算符和 ALL 运算符之间的执行时间存在如此巨大的差异。我确实很惊讶。我不是 DBA,也不是查询优化方面的专家,但也许有一些我不知道的东西,在开发数据库访问查询时我应该考虑这些。
或者可能与特定 Oracle 实例中的问题有关,而不是与查询有关?我从未在同一数据库的其他实例中注意到此问题。
查看解释计划,我注意到在第二种情况下(而不是在第一种情况下)Oracle 将 ALL 运算符替换为 NOT EXISTS:
not exists
(select 0 from TABLE_JOIN_XX tableA
where tableA.id_parent=:b1 and LNNVL (id<=:b2))
有什么建议吗? 非常感谢。
【问题讨论】:
-
为什么你认为
tableA.id = (SELECT MAX (id) FROM TABLE_JOIN_XX tableB WHERE tableA.id = tableB.id)等于tableA.id >= ALL (SELECT id FROM TABLE_JOIN_XX tableB WHERE tableA.id = tableB.id)? -
id 实际上是一个 id_parent,我现在更正了查询。从概念上讲,如果 A >= 每个(元素集),则 A = MAX(元素集)
-
谢谢,我忘了。