2015-06-11 107 views
0

我想比較具有超過1,000,000行的同一個表的值。以下是我的查詢,需要大約25秒才能獲得結果。MySQL加入性能真的很慢

EXPLAIN SELECT DISTINCT a.studyid,a.number,a.load_number,b.studyid,b.number,b.load_number FROM 
(SELECT t1.*, buildnumber,platformid FROM t t1 
INNER JOIN testlog t2 ON t1.`testid` = t2.`testid` 
WHERE (buildnumber =1031719 AND platformid IN (SELECT platformid FROM platform WHERE platform.`Description` = "Windows 7 SP1")) 
)AS a 
JOIN 
(SELECT t1.*,buildnumber,platformid FROM t t1 
INNER JOIN testlog t2 ON t1.`testid` = t2.`testid` 
WHERE (buildnumber =1030716 AND platformid IN (SELECT platformid FROM platform WHERE platform.`Description` = "Windows 7 SP1")) 
)AS b 
ON a.studyid=b.studyid AND a.load_number = b.load_number AND a.number = b.number 

enter image description here

enter image description here

你能誰能幫我改善查詢以獲得足夠快的結果嗎? 這裏的問題是,即使我有number和load_number索引,查詢不會使用它。我不知道爲什麼它總是被忽略..

感謝。

+2

1)看來你不需要兩個子查詢。只需將所有表格連在一起。 2)不要使用IN(),這對MySQL來說可能很慢。改用連接。 3)不要在子查詢中使用*。 – Tim3880

+0

感謝您的評論,我已經使用所有表格的加入,但它會讓情況變得更糟糕。如果我通過電子郵件向您發送郵件,您是否可以使用此表格進行遊戲? –

+0

你的'選擇'是荒謬的。您正在選擇六列,但根據'on'子句,只有三個值。 –

回答

0

首先,你有一個愚蠢的查詢。您正在檢索六列,但只有三個值。看看on條款。

我認爲最好的方法是使用條件聚集重寫查詢。我認爲有以下等價:

SELECT t1.studyid, t1.load_number, t1.number 
FROM t t1 INNER JOIN 
    testlog t2 
    ON t1.testid = t2.testid 
WHERE t2.buildnumber IN (1031719, 1030716) AND 
     platformid IN (SELECT platformid FROM platform p WHERE p.Description = 'Windows 7 SP1')) 
GROUP BY studyid, load_number, number 
HAVING MIN(buildnumber) <> MAX(buildnumber) 

對於此查詢,你想在platform(Description, platformid)testlog(buildnumber, platformid)t(testid)指標。

+0

感謝您的評論,我試圖做的實際上是從「t」表中檢索內部版本號1031719的所有值,並檢索另一個內部版本號1030716的所有值,然後比較兩個值之間的值。因爲所有值都基於不同的內部版本號而不同。 –

+0

SELECT a.studyid,a.number,a.ACCELERATION,a.APPLIED_FORCE,a.INTERNAL_FORCE,a.MPC_FORCE,a.SPC_FORCE,a.TRANSLATION,a.VELOCITY,a.load_number,b.studyid,b.number, b.ACCELERATION,b.APPLIED_FORCE,b.IN​​TERNAL_FORCE,b.MPC_FORCE,b.SPC_FORCE,b.TRANSLATION,b.VELOCITY,b。load_number 這是完整的選擇部分.. –

0

問題1:
IN (SELECT ...)優化非常很差。子查詢會一次又一次地重新運行。它看起來像你期待從該查詢中只有一個ID;如果是,請將其更改爲= (SELECT ...)。這樣它將只運行一次。

問題#2:

FROM (SELECT ...) 
JOIN (SELECT ...) ON ... 

優化,因爲無論子查詢甚少。你可以把兩個子查詢合併爲一個,就像Gordon試圖做的那樣?如果不是,則將其中一個放入TEMPORARY TABLE中,併爲該表添加適當的索引,以便ON能夠使用它。可能PRIMARY KEY(studyid, load_number, number)

腳註:MySQL的最新版本已經通過動態生成指數由上這些問題的改進。你使用什麼版本?

+0

謝謝你的評論。我想知道,一旦我創建一個臨時表,那麼我是否需要加入臨時表的表?或如何使用Select語句應用臨時表?你能向我解釋一下嗎? –

+0

'CREATE TEMPORARY TABLE xx(PRIMARY KEY ...)SELECT ...';然後...'SELECT ... FROM(SELECT ..另一個子查詢...)JOIN xx on .. 3 fields ..等等' –