このブログでも何回か登場している「ヤヴァイシステム」で、またまた驚きの大発見をしてしまいました。。。
なかなか一覧表示のレスポンスが上がらないので、あの手この手でSQLをチューニングしていました。
そうするとどうもボトルネックと思われるストアドファンクションが見えてきました。
そのストアドのロジックを見てみると・・・これまた一見すると「何してるんかわからん」ソースなのですが、本当の問題はそれではありません。
実はテーブルの1カラムに複数のIDが文字列として埋め込まれているため、ループ処理で文字列を切り出しながらマスターテーブルの値を取得していたのです!!
言葉じゃ分かりにくいと思うので、表形式で表すとこんなイメージ。
[受注テーブル]
受注番号 | 顧客 | 商品コード |
---|---|---|
0001 | 田中さん | ABC001, LMN123, XYZ111 |
0002 | 佐藤さん | PQR456, HIJ222 |
[SQL]
SELECT 受注番号, 顧客, fnc_shohin(商品コード) --この中で文字列を分割して1件ずつ商品マスターを取得... FROM 受注テーブル
[一覧の表示結果]
受注番号 | 顧客 | 商品 |
---|---|---|
0001 | 田中さん | 肉, にんじん, たまねぎ |
0002 | 佐藤さん | マグロ, タコ |
SQLをちょっとでもかじったことのある方なら分かると思いますが、商品コードが明細用のテーブルではなく、親テーブルにこんな風に登録されていたら、簡単に商品マスターと結合できなくなるのは当たり前ですよね・・・。
上の例では単純化するために商品コードだけがカンマ区切りで格納されていますが、実際のシステムでは他のカラムにもいくつかこのようにデータが格納されています。
なので、一覧を表示するたびに毎回すごい数のループ処理がストアドファンクションを経由して実行されているのです。
あいたたた・・・こりゃどう考えても遅いわ!!
やっぱりひどい設計はパフォーマンスのようなユーザーの目に見える品質も悪くなりますし、コーディングもすぐに複雑化してしまうことを改めて実感しました。
だから、おいらはずっとシステムの設計品質は超重要だと信じていますし、そのために勉強をし続けているのですよ。
2015.8.5 追記
ひどすぎてつらい・・・
— へんたガチャDIY (@HENTA0213) 2015年8月5日
何を思ってこんな設計にしたのか小一時間問いただしたい https://t.co/qLHkvr7RoN
何を考えていたのかはわかりませんが、作った本人は自信満々で自分のシステムには何の落ち度もないように振る舞っておりました。 https://t.co/cN4GfZN3cd
— Junichi Ito (伊藤淳一) (@jnchito) 2015年8月5日
ちなみに、SQLアンチパターンという本にこれと同じ話が載っているようです。
- 作者: Bill Karwin,和田卓人,和田省二,児島修
- 出版社/メーカー: オライリージャパン
- 発売日: 2013/01/26
- メディア: 大型本
- 購入: 9人 クリック: 698回
- この商品を含むブログ (46件) を見る