2017-05-30 53 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

第二個查詢可能來執行交叉聯接然後過濾的結果,雖然它會是一個很老的甲骨文的版本是愚蠢的。但是您需要查看查詢計劃才能找出答案。如果他們始終表現出不同的表現,那麼我保證查詢計劃會有所不同。