与WHERE子句相比,IS NULL检查在ON子句中性能更差
问题描述:
该查询运行得很好,但如果将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
答
既然是左连接,查询是不等同,因此没有可比性。
当您在ON
子句的右表中放置列的过滤器时,过滤器将检查表中列的实际值是否存在空值。当右表中没有匹配左表中的行时,JOIN仍然会为此列生成空值。
当您在WHERE
子句中放入相同的筛选器时,筛选器将检查列中是否存在空值,或者右表中是否存在左表中的行。
原则上,它应该不重要,因为优化器应该处理这个问题(如果查询是可比较的)。 – MrTux