[DB] 副問合せと相関副問合せの違い [SQL]

どうも、tatsuです!

今回はSQLの副問合せと相関副問合せの違いについて書いていこうと思います。

副問合せ

構文の()で囲まれたSELECTの部分が副問合せです。

構文
SELECT 列名
FROM テーブル名
WHERE 条件(SELECT・・・)

副問合せとは、SELECT文やUPDATE文などの中に別のSELECT文を含んでいる問い合わせのことを指します。
副問合せを使うことで、条件にSELECT文の結果を使用することができます。
例えば、Aプロジェクト参加メンバーテーブル(PROJECT_A_MEMBER_TBL)の中から正社員テーブル(REGULAR_EMP_TBL)に存在する社員を抜き出したい場合、以下のようなSELECT文で抜き出すことができます。


SELECT EMPLOYEE_NAME
FROM PROJECT_A_MEMBER_TBL
WHERE EMPLOYEE_NAME IN (SELECT REGULAR_EMP_NAME FROM REGULAR_EMP_TBL)
上記の例では、正社員テーブル(REGULAR_EMP_TBL)の社員名(REGULAR_EMP_NAME)の中に含まれているAプロジェクト参加メンバーテーブル(PROJECT_A_MEMBER_TBL)の社員名(EMPLOYEE_NAME)が結果として取得されます。つまり、Aプロジェクト参加メンバーの中で正社員の人を抜き出すということです。

副問合せの特徴は、副問合せを処理した後に主問合せを処理するということです。

相関副問合せ

構文の()で囲まれたSELECTの部分が相関副問合せです。

構文
SELECT 列名
FROM テーブル名1
WHERE EXISTS(またはNOT EXISTS) (SELECT * FROM テーブル名2 WHERE テーブル名2.列名 = テーブル名1.列名)

相関副問合せとは、EXISTSを使用してテーブル1の対象列の値がテーブル2の対象列に存在するかをチェックします。
相関副問合せと使うことで、INを使用した副問合せと同じ結果を取得することができます。
しかし、この場合相関副問合せを使用した方が通常速度は向上します(理由は後述)。
副問合せと同じ例で相関副問合せを使うと以下のようなSQLになります。


SELECT A_TBL.EMPLOYEE_NAME
FROM PROJECT_A_MEMBER_TBL A_TBL
WHERE EXISTS (SELECT * FROM REGULAR_EMP_TBL REG_TBL WHERE REG_TBL.REGULAR_EMP_NAME = A_TBL.EMPLOYEE_NAME)
相関副問合せの中で外側の問合せのテーブル列を指定しているため、列名には必ずテーブルの別名を付けてください(A_TBL.EMPLOYEE_NAMEの部分など)。

相関副問合せの特徴は、主問合せのテーブルを、相関副問合せで他のテーブルと結合して存在するかを一行ずつ処理するということです。

どっちを使うべき?

前述したとおり、通常はIN句を使った副問合せより、EXISTSを使った相関副問合せを使用した方が速度は向上します。
その理由は、IN句を使った副問合せでは、先に副問合せを行ったあとに主問合せの1件ごとに副問合せの結果に含まれているかを確認するため、副問合せの処理件数×主問合せの件数 の時間がかかってしまいます。
しかし、EXISTSを使った相関副問合せでは結合キー部分にインデックスが定義されていればインデックスだけを使用して検索できるため、副問合せの処理件数+主問合せの件数 の時間で済むことになるからです。
よって相関副問合せを使用した方が良いです。

まとめ

いかがでしたか?
副問合せと相関副問合せでは何が違うのか、うまく伝えられていたら幸いです。
それでは!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です