2011-06-14 126 views
0

我嘗試避免子查詢,因爲他們通常比正確的連接性能低得多。MySQL - 左連接和不在

這是我目前不工作查詢:

SELECT 
    a.`email_list_id`, a.`category_id`, a.`name` 
FROM 
    `email_lists`AS a 
    LEFT JOIN `email_autoresponders` AS b 
     ON (a.`website_id` = b.`website_id`) 
WHERE 
    a.`website_id` = [...] 
    AND a.`category_id` <> 0 
    AND a.`email_list_id` <> b.`email_list_id` 
GROUP BY 
    a.`email_list_id` 
ORDER BY a.`name` 

此查詢的工作:

SELECT 
    `email_list_id`, `category_id`, `name` 
FROM 
    `email_lists` 
WHERE 
    `website_id` = [...] 
    AND `category_id` <> 0 
    AND `email_list_id` NOT IN ( 
     SELECT 
      `email_list_id` 
     FROM 
      `email_autoresponders` 
     WHERE `website_id` = [...] 
    ) 
GROUP BY 
    `email_list_id` 
ORDER BY 
    `name` 

有什麼辦法用左連接做到這一點?我嘗試了許多不同的選擇。

+0

永遠不要對性能的假設。工作查詢的時間是什麼? – 2011-06-14 21:49:00

+0

.0014,但這是一個基本的例子,它總共搜索5條記錄。如果它搜索5,000條記錄,我懷疑它會執行相同的操作。 – 2011-06-14 21:51:17

回答

2

重新考慮它一下後,這可能工作,我相信:

SELECT 
    a.`email_list_id`, a.`category_id`, a.`name` 
FROM 
    `email_lists`AS a 
    LEFT JOIN `email_autoresponders` AS b 
     ON (a.`website_id` = b.`website_id` and a.`email_list_id` = b.`email_list_id`) 
WHERE 
    a.`website_id` = [...] 
    AND a.`category_id` <> 0 
    AND b.`email_list_id` is NULL 
GROUP BY 
    a.`email_list_id` 
ORDER BY a.`name` 
+0

不一樣的邏輯 - 'email_list_id'的相等不是他的連接條件,所以檢查NULL值並不能保證任何東西。 – 2011-06-14 21:55:39

+0

沒有記錄返回 - 我稍微改變了連接,它確實有效,謝謝! – 2011-06-14 21:56:04

+0

@djacobson up剛剛固定,已經:) – 2011-06-14 21:56:14

0

對於初學者來說,在email_list_id添加不平等檢查連接標準,而不是你的WHERE子句中有它:

LEFT JOIN `email_autoresponders` AS b 
    ON (a.`website_id` = b.`website_id` 
     AND a.`email_list_id` <> b.`email_list_id`) 

雖然我不知道的情況你提到的廣闊優化通話,這是使用聯接,而不是子查詢的方式...

+0

@ djacobson - 我試過了,它本身不起作用。對於優化,我沒有提出這個問題只回答這個問題,但我想找到類似問題的解決方案,這就是爲什麼我給這個問題一個通用標題。 – 2011-06-14 21:58:38