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つです。

  1. もし結合キー(この場合はid)にインデックスが張られていれば、Class_Bテーブルの実表は見にいかず、インデックスを参照するのみで済む。
  2. existsは1行でも条件に合致する行を見つけたらそこで検索を打ち切るので、inのように全表検索の必要がない。これは not existsの場合でも同様。

inの引数にサブクエリを与える場合、DBはまずサブクエリから実行し、その結果を一時的なワークテーブル(インラインビュー)に格納し、その後、ビューを全件走査します。これは非常にコストがかかり、一般にワークテーブルにはインデックスが存在しません。existsならばワークテーブルは作成されません。
正し、ソースコードの可読性という点に置いては、inはexistsに勝ります。

このスクラップは2023/10/17にクローズされました