2017-02-15 89 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子句中放入相同的筛选器时,筛选器将检查列中是否存在空值,或者右表中是否存在左表中的行。