与WHERE子句

时间:2017-02-15 19:21:03

标签: mysql

此查询运行正常但如果我将AND h2.delete_datetime IS NULL条件从WHERE子句移动到左连接的ON子句中,则查询将永远运行。这让我感到困惑,因为我习惯于将尽可能多的条件放入ON子句中以提高性能(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 bad:

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

1 个答案:

答案 0 :(得分:1)

由于它是左连接,因此查询等效,因此无法比较。

当您在ON子句中的右表中放置列的过滤器时,过滤器会检查表中的列是否实际存在空值。当右表中没有与左表中的行匹配的行时,JOIN仍会为此列生成空值。

当您在WHERE子句中放入相同的过滤器时,过滤器会检查列中是否存在空值,或者右表中是否存在左表中行的匹配。