MySQL で次の SQL クエリが与えられた場合:
SELECT * FROM tableA WHERE tableA.id IN (SELECT id FROM tableB);
MySQL は のSELECT id FROM tableB
各行に対してサブクエリを複数回実行しますtableA
か?
変数やストア プロシージャを使用せずに SQL を高速化する方法はありますか?
を使用するよりも遅いことが多いのはなぜLEFT JOIN
ですか?
MySQL で次の SQL クエリが与えられた場合:
SELECT * FROM tableA WHERE tableA.id IN (SELECT id FROM tableB);
MySQL は のSELECT id FROM tableB
各行に対してサブクエリを複数回実行しますtableA
か?
変数やストア プロシージャを使用せずに SQL を高速化する方法はありますか?
を使用するよりも遅いことが多いのはなぜLEFT JOIN
ですか?
まず、これは MySQL のバージョンに依存します。バージョン 5.6 では、このようなクエリが正しく最適化されると思います。MySQL のドキュメントは、これに関して一貫性がありません。たとえば、ここでは 1 つのことを言います。
次のサブクエリの比較を検討してください。
outer_expr IN (SELECT inner_expr FROM ... WHERE subquery_where)
MySQL はクエリを「外側から内側へ」評価します。つまり、最初に外側の式 outer_expr の値を取得してから、サブクエリを実行し、生成された行をキャプチャします。
この「外側から内側へ」とは、サブクエリが行ごとに評価されることを意味します。これは、MySQL での私の経験と一致しています。
ドキュメントは、別の方法でここに示唆しています:
MySQL 自体が行ういくつかの最適化は次のとおりです。
- MySQL は、無相関サブクエリを 1 回だけ実行します。EXPLAIN を使用して、特定のサブクエリが実際に無相関であることを確認します。
- MySQL は、サブクエリの選択リスト列がインデックス化されている可能性を利用するために、IN、ALL、ANY、および SOME サブクエリを書き換えます。
この声明は条項に言及していないと思います。in
おそらく何が起こるかというと、インデックスをチェックするためにサブクエリが相関サブクエリとして書き直され、(インデックスの存在に関係なく) 複数回実行されることです。