2017-05-30 25 views
0

我想优化使用内部联接的查询,并且我对两个非常类似的查询之间的性能差异感到困惑。试图了解两个内部联接查询之间的行为差​​异

我希望对此有所了解。

的表是这样的:

骨料:

+-recid(key)-+-avg---+ 
+------------+-------+ 

历史:

+-recid(key)-+-value-+ 
+------------+-------+ 

的目的是让,对于一个给定的密钥(假设1234),AVG和值。

我已经尝试了两个查询谁似乎很相似,我说:

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

标记您正在使用的dbms。不同的产品以不同的方式优化。 – jarlh

+1

BTW,你运行两个查询多次,在不同的顺序? (冷/热数据。) – jarlh

+0

是的,我已经试过了,这是非常reproductible,一个是一贯〜5慢于其他 – Maxime

回答

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)上有索引,那么这两个版本在几乎所有我能想到的数据库中应该有非常相似的执行计划。这两个索引将被推荐用于这样的查询。

一种可能性是冷与热缓存相比。第一次运行查询时,需要将数据加载到内存中。这可能需要更长时间。为了适当的时机,你需要考虑到这一点。

最后,如果您真的想了解其中的差异,那么您需要查看执行计划。大多数数据库提供了一种简单的方式来“解释”查询的运行方式。

0

不能确定,但​​可能是您的第二个查询执行计划已经被缓存,因此数据库优化器无需携带一个。顺便说一句,你的第一个查询应该是变化如下使用ANSI风格的JOIN语法

SELECT a.avg, b.value FROM aggregates a 
JOIN history b ON a.recid = b.recid 
WHERE a.recid = 1234 
0

第二个查询可能来执行交叉联接然后过滤的结果,虽然它会是一个很老的甲骨文的版本是愚蠢的。但是您需要查看查询计划才能找出答案。如果他们始终表现出不同的表现,那么我保证查询计划会有所不同。