SQLチューニング
SQL Tuning
計測(ベンチマーク)とボトルネック特定(プロファイル)を起点に、スキーマ・インデックス・クエリを最適化してDBを速くする手法。新しいハードを足す前にまずやるべきこと。
まず計測、それから改善(鉄則)
チューニングの大原則は**『推測するな、計測せよ』**。やみくもに直すのではなく、まず遅い箇所を特定します。
図を描画中...
- Benchmark:
ab(Apache Bench)のようなツールで、高負荷時の挙動をシミュレート。 - Profile: slow query log(遅いクエリの記録)で、どのクエリが足を引っ張っているか特定。
インデックスの効果(最重要)
インデックスは本の『索引』です。索引がなければ目的の語を探すのに全ページめくる(全テーブルスキャン = O(n))。索引があれば一瞬で該当ページに飛べます。
DBのインデックスは自己平衡B-treeという木構造で、検索・挿入・削除を**対数時間 O(log n)**で行えます。データが100万件あっても、log₂(100万) ≒ 20回程度の比較で見つかる、という劇的な速さです。
図を描画中...
ただし代償があります: インデックスはメモリを食い、データを書き込むたびにインデックスも更新するので書き込みが遅くなります。だから貼りすぎは禁物。よく検索する列にだけ貼ります。
スキーマ最適化のコツ
| 項目 | 指針 | 理由 |
|---|---|---|
| 固定長文字列 | CHAR | ランダムアクセスが速い |
| 可変長文字列 | VARCHAR | 無駄な領域を使わない |
| 通貨 | DECIMAL | floatだと誤差が出る |
| 巨大バイナリ | BLOBは避ける | DBが重くなる(別ストレージへ) |
| NULL可否 | できればNOT NULL | 最適化が効きやすい |
補足: CHARは長さ固定なので末尾を探す必要がなく高速、VARCHARは文字列末尾の探索が要る分わずかに不利、というトレードオフがあります。
その他の武器
- 高コストなJOINを非正規化で回避(前述のdenormalization)。
- パーティション: テーブルを内部的に分割して、関係する部分だけ走査。
- クエリキャッシュ: 同じクエリの結果を使い回す設定の調整。
つまずきポイント
- インデックスは『多ければ多いほど良い』ではない。読み取りは速くなるが書き込みは遅くなる。読み書きの比率を見て決める。
- チューニングはハード増設より先にやるべき安価な一手。だが万能ではなく、本質的にスケールが必要な規模ではレプリケーションやシャーディングが必要になる。