のんびり精進

調べた情報などをおすそ分けできれば。

【MySQL】NOT EXISTSのサブクエリでOR条件を指定すると遅い

3年以上前に Twitter にメモ的に書いたものなのですが、忘れたときに遡って探し出すのが大変なのでこちらに再メモ。

SELECT * FROM tb1
WHERE NOT EXISTS (
    SELECT * FROM tb2
    WHERE tb2.col1 = tb1.col OR tb2.col2 = tb1.col
);

くっそ遅くて、実行計画を見たらテーブル全体を走査する感じになっていました。

次のようにすると改善します。

SELECT * FROM tb1
WHERE NOT EXISTS (SELECT * FROM tb2 WHERE tb2.col1 = tb1.col)
    AND NOT EXISTS (SELECT * FROM tb2 WHERE tb2.col2 = tb1.col);

このように二つの NOT EXISTS に分けますが、ここで注意が必要なのが AND にする点です。

  • A OR B という条件に該当しない(=A にも B にも該当しない)

  ↓ つまり

  • Aに該当しない AND Bにも該当しない

何年も前にその時点の MySQL 最新版でもなく更に古いもので確認して得た知識です。 新しいバージョンではオプティマイザが賢くなって解決している可能性もあります。 ちゃんと自分で実行計画などを確認しながら書きましょう。