give IT a try

プログラミング、リモートワーク、田舎暮らし、音楽、etc.

Design Horror!

このブログでも何回か登場している「ヤヴァイシステム」で、またまた驚きの大発見をしてしまいました。。。


なかなか一覧表示のレスポンスが上がらないので、あの手この手でSQLをチューニングしていました。
そうするとどうもボトルネックと思われるストアドファンクションが見えてきました。
そのストアドのロジックを見てみると・・・これまた一見すると「何してるんかわからん」ソースなのですが、本当の問題はそれではありません。


実はテーブルの1カラムに複数のIDが文字列として埋め込まれているため、ループ処理で文字列を切り出しながらマスターテーブルの値を取得していたのです!!
言葉じゃ分かりにくいと思うので、表形式で表すとこんなイメージ。


[受注テーブル]

受注番号 顧客 商品コード
0001 田中さん ABC001, LMN123, XYZ111
0002 佐藤さん PQR456, HIJ222


[SQL]

SELECT 
  受注番号, 
  顧客, 
  fnc_shohin(商品コード)  --この中で文字列を分割して1件ずつ商品マスターを取得...
FROM 受注テーブル


[一覧の表示結果]

受注番号 顧客 商品
0001 田中さん 肉, にんじん, たまねぎ
0002 佐藤さん マグロ, タコ


SQLをちょっとでもかじったことのある方なら分かると思いますが、商品コードが明細用のテーブルではなく、親テーブルにこんな風に登録されていたら、簡単に商品マスターと結合できなくなるのは当たり前ですよね・・・。


上の例では単純化するために商品コードだけがカンマ区切りで格納されていますが、実際のシステムでは他のカラムにもいくつかこのようにデータが格納されています。
なので、一覧を表示するたびに毎回すごい数のループ処理がストアドファンクションを経由して実行されているのです。
あいたたた・・・こりゃどう考えても遅いわ!!


やっぱりひどい設計はパフォーマンスのようなユーザーの目に見える品質も悪くなりますし、コーディングもすぐに複雑化してしまうことを改めて実感しました。
だから、おいらはずっとシステムの設計品質は超重要だと信じていますし、そのために勉強をし続けているのですよ。

2015.8.5 追記

ちなみに、SQLアンチパターンという本にこれと同じ話が載っているようです。

SQLアンチパターン

SQLアンチパターン