SQLの外部結合
今回はSQLの外部結合のパターンを考えてみました。
本記事ではMySQLを使用しています。PostgreSQLも対応しています。
外部結合は「LEFT OUTER JOIN」を取り扱っていきます。
LEFT OUTER JOINとは
左側に存在するテーブルと、関連する項目とで
紐づけ、紐づいたものを結合するという動きです。
左側に存在するテーブルと、結合できなかったデータは取得されません。
3パターン
外部結合する方法を3パターンをまとめました。
1.単純に外部結合する。
2.副問い合わせを用いて結合元データを最小にする。
3.With句を用いて、結合元データを最小にし、可読性を向上させる。
3つのパターンのSQLを以下に記載します。
取得できる結果は同じですが、パフォーマンス
可読性の違いを感じて欲しいです。
1.単純に外部結合する。
1 2 3 4 5 6 7 8 9 10 |
--ユーザ情報すべてをログイン情報と結合してから抽出 SELECT mu.user_no ,mu.user_name ,sl.login_time ,sl.logout_time FROM m_user mu LEFT OUTER JOIN s_loging sl USING(user_no) WHERE user_no = 1 |
次のような外部結合になります。
全ての情報を結合してから、必要な情報を抽出しています。
データ量が多くなければ、SQLのパフォーマンスにあまり影響はないような気がしますが
複雑なSQLやデータ量が多いテーブルからの抽出を繰り返すと、パフォーマンスはかなり落ちます。
基本的にはおすすめできないです。
2.副問い合わせを用いて結合元データを最小にする。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
--ユーザ情報を副問い合わせで抽出後、ログイン情報と結合 SELECT mu.user_no ,mu.user_name ,sl.login_time ,sl.logout_time FROM ( SELECT * FROM m_user WHERE user_no = 1 ) mu LEFT OUTER JOIN s_loging sl USING(user_no) |
次のような外部結合のになります。
結合元の情報を絞ってから外部結合しています。
結合元を絞っているので、データ量が多くなっても
全てを結合してから抽出しているわけではないので、パフォーマンスは向上します。
3.With句を用いて、結合元データを最小にし、可読性を向上させる。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
--ユーザ情報を抽出してからログイン情報と結合 WITH user_info AS ( SELECT * FROM m_user WHERE user_no = 1 ) SELECT ui.user_no ,ui.user_name ,sl.login_time ,sl.logout_time FROM user_info ui LEFT OUTER JOIN s_loging sl USING(user_no) |
副問い合わせを使用した書き方から、With句を使用した書き方へ変更しました。
個人的には、With句を使用した方が圧倒的に稼働性が高いと思います。
使いがってもいいですし。
USINGを使用する
ちなみに、外部結合をする際に
USING句やON句を使用します。
可読性を重視した場合、個人的にはUSINGを推奨しています。
まとめ
基本的な考え方ですが、実際の現場のSQLを結合元を絞ってから
外部結合するよう修正を加え、SQLのパフォーマンスを向上させてきた
経験がかなりあります。
基本的な考えでも意外と実践している人ばかりではありません。
本考え方を知り、実践していくだけで、現場では、喜ばれると思います。
人に伝わるSQLを書けるようにしていきたいですね。
コメント