コンシューマ世界でのJOIN禁止、固定長ルールのまとめ
もくじ
私
- JOIN禁止の世界は知らない(1テーブルに1億以上のレコードを扱ったことがない)
- 原則として正規化できるものは正規化してJOINを行い、正規化する必要のないものは正規化しないスタンス
- 1テーブルはどんなに大きくても20カラム限界がセオリー
→正規化できるのではないか、テーブルをわける - 1テーブルが大きく正規化されずに開発されたサービスの保守はしている
情報元
コンシューマでJOIN禁止とされる理由
- スケーラビリティの観点からDBの分割に対応しにくくなる
1億レコード、将来10億レコード以上を想定した設計 - JOINした時に適切にINDEXが張られていないと致命的になる
- JOINそのものが問題なのではなく不適切な実行計画が問題の本質
だから統計情報の自動的な採取はオフ
コンシューマで固定長とされる理由
カラムの型として固定長(CHARとDATE)しか許されない。
- コンシューマ向けサービスでは、データの検索・操作・集計の範囲が広範囲になることはない。
または設計上で回避出来る。 - コンシューマ向けサービスでは、ほとんどのDBアクセスは1ユーザの情報を読み書きするだけ
企業の業務向けシステムと違って、コンシューマではほかのユーザと集計してSUMやGROUP関数を使わない
集計関数の禁止?
- ORDER BYを使っていたら、集計関数を使わない方がデータベースの負荷は高い。集計関数を禁止するなら、ORDER BYを禁止しないと意味がない
データベースの負荷のピークは掛け算
>例えば、JOINを使ったときのリソース使用率が100%で0.1秒、JOINを使わないとき、20%で1秒といった感じになる。たまたま、5人が同時に同じ処理をリクエストしたとしましょう。
>JOINを使ったときは、0.1~0.5秒で終わる。
JOINを使わないときは、全員がほぼ1秒で終わる。← これを重要視しがち>しかし、10人が同時に同じ処理をリクエストしたとしましょう。
JOINを使ったときは、0.1~1.0秒で終わる。
JOINを使わないときは、1~2秒で終わる。← 要件を満たせない≒パンク>データベースサーバでJOINで処理していれば、1秒間に対応できるのは10ユーザ、JOINしていなければ5ユーザで、シングルポイントのデータベースサーバが早くパンクするわけ。完全な同時実行なんて希ですが、処理が長ければ長いほど輻輳する可能性は高くなる。
>結論としては、アプリケーションサーバでソートを肩代わりするか、マスターなどをキャッシュする以外は、下手糞がいなければデータベースサーバで処理した方がデータベースサーバの負荷は減る。巨大だからとか、見当違いも甚だしく全く関係ない。
@see JOIN禁止と固定長カラムについて
SQL最適化の手順
- スロークエリを集計する
遅いクエリから対応 - 実行計画を確認する
「EXPLAIN」を利用し、UPDATEはSELECTに置き換える
type=all, type=indexでrowが多いクエリ、WHEREの箇所にINDEXを張る - 3-1. SQLの変更
3-2. INDEXを張る
3-3. テーブル構成を見直す