2016-12-26 55 views
3

我試圖解釋,讓我爲難,性能問題選擇...JOIN性能與在一個循環中

我有2個表,A和B.

表A定義的對象:

+----+--------------+ 
+ ID + other_things + 
+----+--------------+ 
+ 1 + ~~~~~~~~~~~~ + 
+ 2 + ~~~~~~~~~~~~ + 
+ 3 + ~~~~~~~~~~~~ + 
+----+--------------+ 

此表中有575行。

表B定義了所述對象的一些屬性。

+----+-------------+-------------+ 
+ ID + prop_type + prop_value + 
+----+-------------+-------------+ 
+ 1 + prop1 + foo  + 
+----+-------------+-------------+ 
+ 1 + prop2 + toto  + 
+----+-------------+-------------+ 
+ 3 + prop2 + lorem  + 
+----+-------------+-------------+ 

此表中有20254行。

的目的是讓所有的「PROP2」值的表A中的項目

有些用戶已經在這裏種足以幫助我建立了「良好」的解決方案(見問答。41331902 ):

SELECT A.ID, B.prop_value 
FROM A LEFT JOIN 
    B 
    ON A.ID = B.ID AND B.prop_type = 'prop2'; 

該查詢在大約20秒內執行。

然而,目前使用的其他版本,我試圖改善開頭:

FOR (
SELECT ID as id_a FROM A 
) 
DO 
prop = (select prop_value from B where prop_type = 'prop2' and id = id_a); 
write id_a || ' ' || prop; 
END 

這給了相同的結果,但查詢在1.5秒內完成......

這是我從我在網上閱讀的理解比JOIN應該是更好的一個循環,但實際結果說不然...

我試圖改變表的順序(即大連接小),但只會讓事情變得更糟(最多1分鐘E)。

你能幫我理解這裏會發生什麼嗎?

附註:我不能得到執行計劃,因爲數據庫引擎不允許它(AspenTech的的SQLPlus)

非常感謝您的幫助

+0

糟糕。我將所有變量重新命名以保持一般性,其中一些已經被中斷。 – Maxime

+0

您的循環代碼等同於內部連接,並且您將性能與編碼爲外部連接的查詢進行性能比較,但由於您的where子句而實際上是內部連接。將第一個查詢作爲顯式內部聯接運行,並將其用於比較。 –

+0

@DanBracuk我不明白你的意思。如果我在第一個查詢中用'INNER JOIN'替換我的'LEFT JOIN',我得不到相同的結果,即表A中的表B中沒有'表'中的'prop2'的項。 對不起,新手評論... – Maxime

回答

2

如果你有這個疑問:

SELECT A.ID, B.prop_value 
FROM A LEFT JOIN 
    B 
    ON A.ID = B.ID AND B.prop_type = 'prop2'; 

而且要加快步伐,創建B索引:

CREATE INDEX idx_b_id_type_value ON B(id, prop_type, prop_value); 

這應該會大大提高性能。

如果B有一個索引,其中prop_type是索引中的第一個鍵,那麼您的雙查詢版本會更快。我應該補充一點:我沒有Aspen SQL的經驗。另一種可能性是它只有一個糟糕的優化器。

+0

是我的一個錯誤,我刪除了太多。有一個'哪裏'的條件來獲得相同的結果。 – Maxime