2017-05-11 105 views
0

我有一個MySQL查詢,內部連接和一個左連接以及數據庫中的大量數據,並且運行速度很慢。這大致是我的查詢:MySQL LEFT JOIN命令的ON條件

SELECT 
    main_table.* 
FROM 
    main_table 
INNER JOIN 
    ... 
LEFT JOIN 
    second_table ON (main_table.id = second_table.ref_id AND second_table.type = 'foo' AND second_table.bar IS NULL 
WHERE 
    second_table.id IS NULL 
; 

main_table的條目可以second_table一個或多個被引用條目。我想從main_table獲得所有結果,即second_table中沒有結果,或者只有第二個表中的不相關數據(type 'foo'bar爲NULL)。

縱觀進入EXPLAIN,MySQL的搜索bar IS NULL第一,其次是type = 'foo',仍然會導致成千上萬的結果,而檢查ref_id第一隻留下很少的結果在檢查其他條件。

我只有一個指數ref_id,而不是typebar,我不覺得有必要對其進行索引,如果我能得到ref_id第一查詢搜索。

- 編輯:我注意到,在數據庫的副本(其中有實際的數據和運行速度慢)確實也對typebar指數分別,所以這可能就是爲什麼MySQL的喜歡bar比其他鍵。我正在考慮跨越多個字段的密鑰.--

有沒有人有一個想法如何優化這種查詢?是否有可能在條件下使用特定順序強制MySQL?


「解決方案」:我添加了一個跨越所有相關字段的索引。

我不認爲這是一個真正的解決方案,因爲我相信,如果JOIN先在索引ref_id上完成,它也會更快。當這是唯一的索引時,它可能是這樣做的,但是我的同事有想在其他字段中單獨添加索引的想法,因爲某種原因,可能需要在我們的應用程序的其他地方。

+0

即使你可以保證一個訂單,我認爲你可以,如果你改變查詢可能會發生什麼?然後訂單可能會再次改變。爲什麼不在任何可能有用的地方添加索引? –

+2

我不回答問題,在他們的單詞'想'。這只是一個規則。 – Strawberry

+0

我現在使用谷歌搜索「想要和想要什麼不同」)) –

回答

0

如果將「不相關」行移到where部分會發生什麼? 在我看來,DB應該有一個更輕鬆地連接表,並使用索引

喜歡的東西

SELECT 
    main_table.* 
FROM 
    main_table 
INNER JOIN 
    ... 
LEFT JOIN 
    second_table ON main_table.id = second_table.ref_id 
WHERE 
    second_table.id IS NULL OR 
    (second_table.type = 'foo' AND second_table.bar IS NULL) 
+0

這也是我首先想到的。你的查詢*包含*'type ='foo'',但我需要在最終結果中排除它們(注意我的WHERE second_table.id IS NULL)。如果第二個表中只有一個符合條件的匹配,我想排除主要結果。 – Simon

+0

你的意思是說,如果main_table中的一行有1個相關的行和1個不相關的行,它不應該出現在結果中,但我的查詢會有它。對? –

+0

是的,就是這樣。 – Simon

0

在MySQL JOIN快則LEFT JOIN所以你可以寫你這樣的查詢。

SELECT 
    main_table.* 
FROM 
    main_table 
INNER JOIN 
    ... 
LEFT JOIN (SELECT main_table.*,second_table.* FROM main_table 

JOIN second_table ON main_table.id = second_table.ref_id AND 

second_table.type = 'foo' AND second_table.bar IS NULL) AS main_table2 ON 

main_table2.id = main_table.id 

WHERE 
second_table.id IS NULL;