我有一个使用非常复杂的数据库视图的Web应用程序来检索一些看似非常慢的数据,最多只需要3分钟即可完成。经过彻底调查后,我发现问题的原因是什么。 在我的代码中,我在WHERE子句中使用以下条件来仅检索连接表的LAST元素:
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用NOT EXISTS替换ALL运算符:
not exists
(select 0 from TABLE_JOIN_XX tableA
where tableA.id_parent=:b1 and LNNVL (id<=:b2))
有什么建议吗? 非常感谢。
答案 0 :(得分:2)
您的查询似乎格式不正确。这是你的陈述:
WHERE tableA.id = (SELECT MAX(id) FROM TABLE_JOIN_XX tableB WHERE tableA.id = tableB.id)
您正在列id
上执行相关子查询。然后您选择最大值。子查询只能返回tableA.id
或NULL
,因此这相当于:
WHERE EXISTS (SELECT 1 FROM TABLE_JOIN_XX tableB WHERE tableA.id = tableB.id)
也许甲骨文有点困惑。在任何情况下,通过使用MAX()
,您说需要处理所有值,因此Oracle可能正在这样做。实际上,它只需要找到一个带有值的行。
TABLE_JOIN_XX(id)
上的索引应该可以帮助更多查询。