我正在尝试优化使用内部联接的查询,我对两个非常相似的查询之间的性能差异感到困惑。
我希望对此有所了解。
表格如下:
聚集体:
+-recid(key)-+-avg---+
+------------+-------+
历史:
+-recid(key)-+-value-+
+------------+-------+
目标是获得一个给定的密钥(让我们假设1234),平均值和价值。
我尝试了两个与我非常相似的查询:
SELECT a.avg, b.value FROM aggregates a, history b
WHERE a.recid = b.recid
AND a.recid = 1234
需要5秒钟才能运行
但是,
SELECT a.avg, b.value FROM aggregates a, history b
WHERE a.recid = 1234
AND b.recid = 1234
在不到一秒的时间内运行。
这两个查询给出了相同的结果。我想了解性能的巨大差异(最终游戏是一个更好的理解,为这个查询实现更好的性能!)
答案 0 :(得分:0)
首先,学会使用正确的显式JOIN
语法:
SELECT a.avg, h.value
FROM aggregates a JOIN
history h
ON a.recid = h.recid
WHERE a.recid = 1234;
这不会影响性能,但它是正确的现代语法。
假设您在aggregates(recid)
和history(recid)
上有索引,那么这两个版本应该在我能想到的几乎任何数据库中都有非常相似的执行计划。对于像这样的查询,建议使用这两个索引。
一种可能性是冷和温缓存。第一次运行查询时,需要将数据加载到内存中。这可能需要更长时间。为了正确计时,您需要考虑到这一点。
最后,如果您真的想了解其中的差异,那么您需要查看执行计划。大多数数据库提供了一种“解释”查询运行方式的简单方法。
答案 1 :(得分:0)
不确定但可能是您的第二个查询执行计划已经被缓存,因此DB优化工具不需要带来一个。顺便说一句,您的第一个查询应该是如下更改以使用ANSI样式JOIN语法
SELECT a.avg, b.value FROM aggregates a
JOIN history b ON a.recid = b.recid
WHERE a.recid = 1234
答案 2 :(得分:0)
第二个查询可能正在对结果执行交叉连接然后过滤,尽管它必须是Oracle的一个非常旧的版本才是那么愚蠢。但是你需要查看查询计划才能找到答案。如果它们始终表现出不同的性能,那么我保证查询计划会有所不同。