此查询运行正常但如果我将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
答案 0 :(得分:1)
由于它是左连接,因此查询不等效,因此无法比较。
当您在ON
子句中的右表中放置列的过滤器时,过滤器会检查表中的列是否实际存在空值。当右表中没有与左表中的行匹配的行时,JOIN仍会为此列生成空值。
当您在WHERE
子句中放入相同的过滤器时,过滤器会检查列中是否存在空值,或者右表中是否存在左表中行的匹配。