WebアプリでのSQL

良く見かけるんだけど
超巨大なSQL書いてる人いるんだ
何考えてんだろう……
一般的なWebアプリなんて、ほぼ掲示板だと思うんだ
たとえばECサイト

  • 登録してある情報を表示して
  • ユーザの住所を登録して
  • 購入データを保存して
  • 管理者が新規受付の情報を"商品取り寄せ中"とか、"発送済み"のステータスに変更する

そう、"表示"して"登録"して"変更"するだけ

なのに何故そこまで巨大なSQLが必要になる


整形していない状態(改行なし 1行80文字)で約30行
整形したら80行ぐらいになるようなSQL


普通にSQL実行しても問題ないんだけど、参照しているテーブルが多くなりすぎてて、運営しているうちにクエリに時間がかかるようになってくる。


商品詳細を取得するようなSQLでもそんな状態
商品数が1000件超えたぐらいからクエリに30秒もかかってるよ!
ナニソレ! 状態
メンテもしにくいし、わかりにくい。


何故1回のSQLで全ての情報を取得しようとするのか。
僕にはそれがわからない。

特に多いのが業務系出身の人。
何故か巨大なSQLを作りたがる。



Webアプリでボトルネックになるのは経験上、SQLによるものが多い。
それこそ、100万行のデータをSQLで全件取得し必要な10個を表示する、なんてSQLも見たことある。(もちろん仕事で)



仕事ではMySQL使ってるんだけど、
僕は基本的に1クエリで参照するテーブルは最大3つぐらいまでと決めている。
それ以上になりそうならクエリ分割して投げて、プログラム側でデータ整形する。(全部インデックス効いてるとかなら別だけど)


そもそもサブクエリはあまり使わない。
まぁ、サブクエリ使わないのは元々使っていたMySQLのバージョンが3系だったってのが大きい。
MySQLでサブクエリサポートされたの4.1からだし
今仕事で使ってるのは5系だけど。
正直集計系以外ではサブクエリいらんだろう。
と、いうかいらないような構造でDB構築する。
必要ならきちんと実行計画見てから使う。(Explainとかね)


とか言うと『クエリ発行回数減らすためだよ!』とか言う人いるけど
そのために30秒かかるクエリ投げるのか。
0.02秒〜0.1秒のクエリを3回ぐらい投げて、プログラムでデータ整形した方がはるかにユーザフレンドリだろ と思う


『Webサーバの負担減らすためだよ!』とか言う人もいる。
30秒プロセスが待ちになるのと、1秒で処理終了するの、どっちが軽いかな?
その間にもhttpdプロセスは増えると思うんだ。
そっちのが問題じゃね?
そもそもWebサーバの増強はわりと簡単だと思う。
ロードバランサとかあるし。
画像だけ別ドメインとかから取得するとかいう方法もあるし。


集計系は話が別だ。
夜間、もしくは早朝のアクセスの比較的少ない時間にバッチを実行し、集計済みデータを作る。
バッチは10分かかろうが20分かかろうがかまわない。(早いに越したことはないけど・・・・・・)
そうすることで前日までのデータは集計済みのデータをそれこそSQL1本で取得できる。



僕の知っている人に変った人がいた
たとえばアクセス集計とか購入集計
前日までのデータって再計算必要ないじゃない。
それこそバッチ流せば集計済みデータ生成できて、参照のみで早く、負荷かけずに閲覧できる。
管理画面で当日分も集計みたい、と言われれば、当日分ぐらいならその都度集計してやればいい。(超大規模なら話は別だ)
でもその人、何故かユーザがアクセス、購入した段階で集計してる。
流石にそれはないだろう・・・・・・


当然まともな人とか、超巨大なSQL書いてても普通に早いSQL書く人もいる。
けれども、Web業界で5年ぐらいやってて思うのは
"SQL苦手な人多いなぁ・・・・・・"
ってことと
"業務系から流れてきてる人多いなぁ"
ってこと。

まぁ、僕はSQL苦手なんですけどね。
サブクエリは使わないんじゃなくて、使えない人なんで。