
「相関サブクエリ」とは何か?
複数行値が返って来るようなサブクエリを作成した場合に、テーブルのある特定部分に対象を絞ることで、WHERE句で述語(=、<、>、EXISTS等)を使って比較できるようにする目的で使われます。
本来、サブクエリは、「スカラ・サブクエリ」(単一列、単一行が返って来るサブクエリ)にしない限りは、述語(=、<、>、EXISTS等)は使えなかったですが、相関サブクエリを使えば述語を使えるようになります。
例えば、下記のようなサブクエリは「相関サブクエリ」と言えます。
1 2 |
SELECT * FROM USER_MASTER A WHERE EXISTS (SELECT * FROM AUTHORIZATION B WHERE A.USER_ID = B.USER_ID ) |
肝としては、サブクエリの中で、WHERE句を使用して、その条件としてサブクエリの外の値を参照することですね。
「相関サブクエリ」のデメリット
一般的には、パフォーマンスは悪くなります。
「相関サブクエリ」を使う場合の注意点
必ず、WHERE句で対象を絞る際は、サブクエリの中に記述するようしましょう。
サブクエリの外にWHERE句を指定する形でも問題なさそうに見えますが、エラーになってしまうので注意です。
「結合」と「相関サブクエリ」の使い分け
結論
基本的に「結合」を記述できるのであれば、「結合」を使うのが良い。
理由としては、相関サブクエリをスカラサブクエリとして使うと、結果行数の数だけ相関サブクエリを実行することになるため、かなり高コストな処理になるからです。
相関サブクエリ のユースケース
- EXISTSを使うケース(JOINだと重複行が取得できてしまったり、不要行を取得できてしまう。)
- MySQLのようにウインドウ関数(ROW_NUMBER関数)が使えないケース
ウインドウ関数
基本的には、結合も相関サブクエリ もウインドウ関数に書き換えた方がパフォーマンスも可読性も上がるケースが多いです。
優先度的には下記のようになるでしょう。
1 |
ウインドウ関数 > 結合 > 相関サブクエリ(状況による) |
ただし、ウインドウ関数もMySQLは8.0以上じゃないとサポートしていないので注意です。よくAWSのRDSとかだとAuroraがMySQL5.7になっているのでウインドウ関数を使いたくても使えないので相関サブクエリで代用するというケースは多いです。
この記事へのコメントはありません。