2017-02-15 5 views
1

このクエリは正常に実行されますが、AND h2.delete_datetime IS NULL条件をWHERE句から左側結合のON句に移動すると、クエリには永遠にかかります。これは、パフォーマンスを向上させるためにできるだけ多くの条件をON節に入れることに慣れているためです(ON節の条件が多いほど、結合する行の数が少なくなり、考慮する必要がある行が少なくなることを意味します)。ここでは正反対のことが当てはまり、なぜ私は不思議に思っています。IS NULLチェックはWHERE句と比較して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 

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は、左側のテーブルの行に対して右側のテーブルに一致する行がない場合でも、この列に対してnullを生成します。

WHERE句に同じフィルタを置くと、フィルタはその列にヌルがあるかどうかをチェックします。または、左側のテーブルの行に対して右側のテーブルに一致するものがないかどうかを確認します。

関連する問題