SQL Server | LEFT JOIN vs NOT EXISTS

【注目記事】

・SEの転職体験談 | 受託開発から自社製品開発へ
・SIer勤務のSEがパソナキャリアに相談してみた
・SIer勤務のSEがマイナビエージェントに相談してみた

ある値が別のテーブルに存在しないことを確認する方法に、「LEFT JOIN」と「NOT EXISTS」の2つの方法があります。

どちらを使えば良いのか迷うことがあったので、パフォーマンスの比較をしました。

テスト環境

Microsoft SQL Server Developer (64-bit)

データベースの作成

テーブルの作成

学生テーブルの作成

学生のIDと名前を保持するテーブルです。

高得点者テーブルの作成

高得点の学生のIDを保持するテーブルです。

テストデータの作成

学生テーブルのテストデータ作成

高得点者テーブルのテストデータ作成

パフォーマンスの確認

LEFT JOIN、NOT EXISTSそれぞれで、高得点者テーブルにIDが存在しない学生の名前を学生テーブルから取得します。

それぞれで処理時間を計測し、パフォーマンスを比較します。

LEFT JOIN

実行するSQL

処理時間

CPU 時間 = 4953 ミリ秒、経過時間 = 68103 ミリ秒

NOT EXISTS

実行するSQL

処理時間

CPU 時間 = 7297 ミリ秒、経過時間 = 70791 ミリ秒

結果の解釈

処理時間(経過時間)を比較すると、約2秒ほどLEFT JOINの方が処理時間が短い結果になりました。

ただし、この後何回か実行しましたが毎回経過時間は異なり、かつ両者は毎度同じくらいになったのでほぼ違いはないと言えます。

この結果は意外でした。

NOT EXISTSはIDが見つかった時点で高得点者テーブルの探索を終えるのに対して、LEFT JOINは見つかってもみつからなくても全ての行を探索するはずなので、処理時間はNOT EXISTSの方が早くなると予想していたからです。

実行プランを確認しても、NOT EXISTSの結合はRight Anti Semi Joinで、LEFT JOINはRight Outer Joinです。

Right Anti Semi Joinは該当行がみつかった時点で処理を完了し、Right Outer Joinは全ての行を確認するまで処理を継続します。

さらに、LEFT JOINはNULLチェックのためのフィルタ処理もあるので、コストが高いはずです。

高得点者テーブルのデータ数が少なすぎることが原因で処理時間に違いがでなかったのかと思い、高得点者テーブルのデータ数を増やしても結果は変わりませんでした。

また時間があるときに、再度検証しようと思います。

参考書籍

SQLスキルを高めるためのおススメ書籍

SQLのスキルを高めるには、学校の試験勉強と同じように多くの問題を解いてみるのが効率的です。

『スッキリわかるSQL入門 第2版 ドリル222問付き! (スッキリシリーズ)』は、SQLの基本的な内容の解説に加え、200問を超える問題が掲載されているので、SQL初心者が学習に使うのにおススメです。

実際、この書籍を新卒1年目の新人さんに2-3週間かけて取組んでもらったことがあり、書籍を読んだ後に簡単なSQLの改修を任せましたが、基本的な部分にはつまずかずに改修を進められました。

コメントを残す

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