SDN
← 概念一覧へ
データベース

SQLチューニング

SQL Tuning

計測(ベンチマーク)とボトルネック特定(プロファイル)を起点に、スキーマ・インデックス・クエリを最適化してDBを速くする手法。新しいハードを足す前にまずやるべきこと。

キーポイント
  • 手順: benchmark(負荷をかけて計測, abツール等)→ profile(遅い箇所を特定, slow query log)→ 改善 → 反復。
  • スキーマ最適化: 固定長はCHAR、可変長はVARCHAR。通貨はDECIMAL、BLOBは避ける、NOT NULL制約。
  • 良いインデックス: 自己平衡B-treeで対数時間(O(log n))の検索/挿入/削除を実現。
  • 高コストなJOINは非正規化で回避。テーブルのパーティション、クエリキャッシュのチューニングも。
  • 短所: インデックスはメモリを使い、書き込みを遅くする(増やしすぎ注意)。
トレードオフ

チューニングはハードを増やさずに性能を引き出せる費用対効果の高い第一手。ただしインデックスは検索を速くする代わりにメモリを消費し、書き込み(挿入・更新・削除)を遅くする。インデックスの貼りすぎは逆効果。非正規化と同様、読み取りと書き込みのバランスを見て最適化する必要がある。

まず計測、それから改善(鉄則)

チューニングの大原則は**『推測するな、計測せよ』**。やみくもに直すのではなく、まず遅い箇所を特定します。

図を描画中...
  • Benchmark: ab(Apache Bench)のようなツールで、高負荷時の挙動をシミュレート。
  • Profile: slow query log(遅いクエリの記録)で、どのクエリが足を引っ張っているか特定。

インデックスの効果(最重要)

インデックスは本の『索引』です。索引がなければ目的の語を探すのに全ページめくる(全テーブルスキャン = O(n))。索引があれば一瞬で該当ページに飛べます。

DBのインデックスは自己平衡B-treeという木構造で、検索・挿入・削除を**対数時間 O(log n)**で行えます。データが100万件あっても、log₂(100万) ≒ 20回程度の比較で見つかる、という劇的な速さです。

図を描画中...

ただし代償があります: インデックスはメモリを食い、データを書き込むたびにインデックスも更新するので書き込みが遅くなります。だから貼りすぎは禁物。よく検索する列にだけ貼ります。

スキーマ最適化のコツ

項目指針理由
固定長文字列CHARランダムアクセスが速い
可変長文字列VARCHAR無駄な領域を使わない
通貨DECIMALfloatだと誤差が出る
巨大バイナリBLOBは避けるDBが重くなる(別ストレージへ)
NULL可否できればNOT NULL最適化が効きやすい

補足: CHARは長さ固定なので末尾を探す必要がなく高速、VARCHARは文字列末尾の探索が要る分わずかに不利、というトレードオフがあります。

その他の武器

  • 高コストなJOINを非正規化で回避(前述のdenormalization)。
  • パーティション: テーブルを内部的に分割して、関係する部分だけ走査。
  • クエリキャッシュ: 同じクエリの結果を使い回す設定の調整。

つまずきポイント

  • インデックスは『多ければ多いほど良い』ではない。読み取りは速くなるが書き込みは遅くなる。読み書きの比率を見て決める。
  • チューニングはハード増設より先にやるべき安価な一手。だが万能ではなく、本質的にスケールが必要な規模ではレプリケーションやシャーディングが必要になる。

関連する概念

この概念で腕試し

関連する 4 問のクイズに挑戦できます。

クイズを解く