SQL緊急救命室

第1回 サブクエリ・パラノイア~副問い合わせ乱用による性能劣化を治療せよ!

この記事を読むのに必要な時間:およそ 7.5 分

ここはとある街の総合病院。

ここには通常の診療科のほかに,一風変わった診療科が存在する。

何軒もの病院をたらいまわしにされた,手の施しようのないSQLや,今すぐに改善が必要なSQLが担ぎ込まれる救命室である。

それがSQL緊急救命室,略してSER(SQL Emergency Room)。

そう,ここは国内でも唯一のプログラミング専門外来である。

ロバート
救命室部長。腕の立つエンジニアだが,口が悪く性格はもっと悪い四十オヤジ。

ヘレン
救命室副部長。若いながらもロバートに次ぐ実力を持つ才媛。救命室の良心。

ワイリー
インターンで救命室に配属された不運な学生。無給で治療から雑務全般にこき使われる。エンジニアとしては新人に毛が生えたレベル。

サブクエリ・パラノイア~サブクエリの功罪

(AM3:00:仮眠室。ソファーでロバートが熟睡しているところへワイリーがやってくる)

……先生,起きてください。


グーむにゃむにゃ。おうっ,そ,そこは。


……先生!


グー。うひゃひゃもっと下。


先生ってば!


うるさい。耳元で怒鳴るな。


先生のほうがずっとうるさいし不気味ですよ(何の夢見てんだ)。起きてください。急患です!

今何時だと思ってる。ほっとけ,しばらく寝てりゃ自然に治ると伝えろ。

風邪じゃないんだから,ダメなコードは自然には治りませんよ。治療が必要なんです。かなり切羽詰まってるみたいですよ。

まったく,面倒な連中だ。…どれ,しかたない,行くぞ。


(救命室。雑然とした器具が散乱しているなか,天井の診察用ライトが寒々しい光を放つ。ロバートたちが入ると,すでにヘレンが診察を始めている)

遅いわよ。連絡を受けたら3分以内に来るのがルールでしょ。


3分で死ぬわけじゃあるまい。それで,患者の様態は。


典型的なサブクエリ・パラノイア(副問い合わせ強迫症)ね。しかも自己結合まで発生させて注1),これじゃクエリを遅くしてくださいとお願いしているようなものよ。

どれ…なるほど,こりゃひどい。おい,テーブル定義もよこせ。


はい,こちらに図1,2,リスト1)。


図1 テーブルのレイアウト

図1 テーブルのレイアウト

図2 リスト1の実行結果

cust_id | seq | price
--------+-----+-------
A       |   1 |   500
B       |   5 |   100
C       |  10 |   600
D       |   3 |  2000

リスト1 サブクエリ・パラノイア 患者1号

SELECT R1.cust_id, R1.seq, R1.price
  FROMReceiptsR1 ()
         INNER JOIN
          (SELECT cust_id, MIN(seq) AS min_seq
             FROMReceipts ※
            GROUP BY cust_id) R2
    ON R1.cust_id = R2.cust_id
   AND R1.seq = R2.min_seq;

 同一テーブルを結合する自己結合

さてワイリー,お前ならどうする。


ええっ,ちょっと待ってください。整理します。このReceipts テーブルは,顧客ごとの購入明細を記録するテーブルで,欲しい結果としては,顧客ごとに最小の枝番(seq)のレコードの金額を求めている,ということですよね。

そうね。この問題で難しいのは,連番の最小値が不確定なことね。必ず最小値が1とか決まっているなら単純にWHERE句で制限するだけでいいのだけど,動的に求めざるをえないの。

ヘレンの言うとおり,もし顧客ごとに必ずseq列の最小値が固定なら,この問題に難しいところはありません。しかし,動的にseq列の最小値を求めるため,患者は結合を使用しています。ここでのポイントは,一時的なビューR2です。これは顧客ごとに最小のseq列を求めています図3)。

図3 リスト1の動作イメージ

図3 リスト1の動作イメージ

注1)
同一のテーブルまたはビューに対する結合。うまく使うと便利ですが,高コストな実行計画が選択されるリスクの高い結合方式でもあります。詳細な解説は参考資料3を参照。

著者プロフィール

ミック

SI企業に勤務するDBエンジニア。主にデータウェアハウス業務に従事している。自身のサイト「リレーショナル・データベースの世界」でデータベースとSQLについての技術情報を公開している。『Web+DB Press』で「SQL緊急救命室」を連載中。

著書:『SQL ゼロからはじめるデータベース操作』(翔泳社,2010)『達人に学ぶ SQL徹底指南書』(翔泳社,2008)訳書:J.セルコ『SQLパズル 第2版』(翔泳社,2007)

Twitter:copinemickmack

SQL緊急救命室:サポートページ

コメント

コメントの記入