2017-02-15 90 views
1

該查詢運行得很好,但如果將AND h2.delete_datetime IS NULL條件從WHERE子句移動到左連接的ON子句中,該查詢將持續進行。這使我感到困惑,因爲我習慣於將盡可能多的條件放在ON條款中以提高性能(ON條款中的更多條件意味着連接的行數少,行數少)。在這裏看來相反,我想知道爲什麼。與WHERE子句相比,IS NULL檢查在ON子句中性能更差

好:

SELECT 
count(*), 
min(h.history_date) AS history_date 
FROM 
history AS h 
LEFT JOIN 
history AS h2 
ON (
    h2.contacts_id = h.contacts_id 
AND h2.history_status_id = 59 
/*AND h2.delete_datetime IS NULL*/ 
) 
WHERE 
    h.history_status_id = 58 
AND h2.contacts_id IS NULL 
AND h.delete_datetime IS NULL 
AND h2.delete_datetime IS NULL 
ORDER BY h.history_date DESC 

VS壞:

SELECT 
count(*), 
min(h.history_date) AS history_date 
FROM 
history AS h 
LEFT JOIN 
history AS h2 
ON (
    h2.contacts_id = h.contacts_id 
AND h2.history_status_id = 59 
AND h2.delete_datetime IS NULL 
) 
WHERE 
    h.history_status_id = 58 
AND h2.contacts_id IS NULL 
AND h.delete_datetime IS NULL 
/*AND h2.delete_datetime IS NULL*/ 
ORDER BY h.history_date DESC 
+0

原則上,它應該不重要,因爲優化器應該處理這個問題(如果查詢是可比較的)。 – MrTux

回答

1

既然是左連接,查詢是等同,因此沒有可比性。

當您在ON子句的右表中放置列的過濾器時,過濾器將檢查表中列的實際值是否存在空值。當右表中沒有匹配左表中的行時,JOIN仍然會爲此列生成空值。

當您在WHERE子句中放入相同的篩選器時,篩選器將檢查列中是否存在空值,或者右表中是否存在左表中的行。