メインコンテンツへスキップ

VillageSQL is a drop-in replacement for MySQL with extensions.

All examples on this page work on VillageSQL. Install Now →
通常のサブクエリは 1 回実行され、答えを返します。相関サブクエリは外側のクエリの 列を参照するため、外側の行ごとに異なる答えを持ち、サーバーはそれぞれについて 再実行しなければなりません。 始める前に mysql -u root -p sakila でクライアントを開いてください。

相関サブクエリの仕組み

COLUMN_LIST を必要な列に、TABLE_NAME をテーブルに、COLUMN_NAME を比較する 列に、AGGREGATE_FUNCTION を内側のクエリが実行する関数に、OUTER_ALIAS と INNER_ALIAS を関係するテーブルの 2 つの名前に置き換えます。 この 2 つのエイリアスがこれを機能させます。内側のクエリが外側のクエリを名前で 参照し、それが相関です。 外側の行ごとに 1 回、その行の値を埋めて問われる質問として読んでください。

答える質問

「平均より長い映画はどれか」には 1 つの平均が必要です。「そのレーティングの 中で平均より長い映画はどれか」には行ごとに異なる平均が必要で、相関サブクエリが 与えてくれるのはそれです。
f2.rating = f.rating が重要な部分です。内側のクエリをテスト中の行に結び付ける ため、G の映画は G の平均と、R の映画は R の平均と比較されます。 その部分を取り除くと、サブクエリはカタログ全体の平均を取り、毎回同じ値になり、 クエリは別の質問に答えます。

行ごとに 1 回実行される

上の実行時間を、サブクエリのレッスンのクエリと比べて ください。あちらは速すぎて計測できません。こちらは 1,000 行に対して 10 分の 1 秒 かかります。正確な数値は環境によって異なりますが、サーバーが内側のクエリを 1 回 ではなく外側の行ごとに評価するためです。 これがトレードオフのすべてです。相関サブクエリは「各行を自分のグループと比較 する」を書く最も明快な方法であり、そのコストはテーブルとともに増えます。 MySQL は一部の相関サブクエリを自分で結合に書き換えますし、同じ質問に 1 パスで 答える別の形もあります。 MySQL におけるサブクエリと JOIN の比較では、その 両方と、どちらになったかを教えてくれるプランの読み方を扱います。

まとめ

  • 各行を、自分のグループから計算した何かと比較するには相関サブクエリを使います。
  • 内側のクエリは外側のクエリを参照しなければならないため、両方のテーブルにエイリアスを付けます。
  • 外側の行ごとに 1 回実行されると考えてください。
  • テーブルが大きいときは、派生テーブルと結合に書き換えます。

関連項目