Closed1
SQL - SQLを速くするぞ -
はじめに
SQLのパフォーマンスチューニングは、DBエンジニアが実務で直面する主要な課題の 1 つです。
中には、「ほとんど唯一の課題」にすらなってる人もいるでしょう。
今回紹介するものとしては、SQLを高速化し、なるべく少ないリソースで実行するためのちょっとしたパフォーマンスチューニングの技術を紹介します。
効率の良い検索を利用する
サブクエリを引数に取る場合、in よりも exists を使う
in述語はその利便性とコードのわかりやすさから、非常に使用頻度の高いツールです。
しかし、便利な反面、in述語はパフォーマンス面から見るとボトルネックになる危険を抱えています。
実際に見ていきましょう。以下のテーブルがあります。
Class_A
id(識別子) | name(名前) |
---|---|
1 | 田中 |
2 | 鈴木 |
3 | 伊集院 |
Class_B
id(識別子) | name(名前) |
---|---|
1 | 田中 |
2 | 鈴木 |
4 | 西園寺 |
-- 遅い
-- select *
-- from Class_A
-- where id in (select id from Class_B);
-- 速い
select *
from Class_A as A
where exists(select * from Class_B as B where A.id = B.id);
existsの方が速いと期待できる理由は以下の2つです。
- もし結合キー(この場合はid)にインデックスが張られていれば、Class_Bテーブルの実表は見にいかず、インデックスを参照するのみで済む。
- existsは1行でも条件に合致する行を見つけたらそこで検索を打ち切るので、inのように全表検索の必要がない。これは not existsの場合でも同様。
inの引数にサブクエリを与える場合、DBはまずサブクエリから実行し、その結果を一時的なワークテーブル(インラインビュー)に格納し、その後、ビューを全件走査します。これは非常にコストがかかり、一般にワークテーブルにはインデックスが存在しません。existsならばワークテーブルは作成されません。
正し、ソースコードの可読性という点に置いては、inはexistsに勝ります。
このスクラップは2023/10/17にクローズされました