第24回: パーティションの考え方 — 巨大テーブルの運用負荷を設計で下げる

章: 第5章: 設計品質を上げる

ログテーブルが数千万件を超えたとき、どう対処しますか?

アクセスログや履歴データを1つのテーブルに蓄積し続けると、削除クエリが重くなり、バックアップに時間がかかり、インデックスが肥大化する問題が起きます。DELETE WHERE accessed_at < '2024-01-01' を流すだけで数十分かかる、というケースも珍しくありません。

MySQLのパーティションを活用すると、月ごと・年ごとにデータを物理的に分割でき、期間削除を ALTER TABLE ... DROP PARTITION の一瞬で完了させることができます。

パーティションの種類と使いどころ

パーティション種別 分割キー 向いているケース
RANGE 値の範囲(日付・IDなど) 月次ログ・期間削除が必要なデータ
LIST 指定した値のリスト 地域コード・カテゴリなど固定値での分割
HASH ハッシュ値で均等分散 均等なI/O分散が目的の場合
KEY MySQL内部キーで均等分散 主キーによる均等分割

実務での第一候補は RANGE パーティション(日付キー) です。期間削除と検索の両方に効果があります。

チェックポイント: パーティションは「全テーブルに適用すべき万能手段」ではありません。WHERE句にパーティションキーが含まれない検索では全パーティションを走査するため、むしろ遅くなることがあります。適用前に EXPLAIN PARTITIONS で動作を確認してください。

実際のコードサンプル


CREATE TABLE access_logs (
  id BIGINT UNSIGNED NOT NULL,
  accessed_at DATETIME NOT NULL,
  user_id BIGINT UNSIGNED,
  PRIMARY KEY (id, accessed_at)
)
PARTITION BY RANGE (TO_DAYS(accessed_at)) (
  PARTITION p202604 VALUES LESS THAN (TO_DAYS('2026-05-01')),
  PARTITION p202605 VALUES LESS THAN (TO_DAYS('2026-06-01'))
);

まとめ & 次のステップ

  • パーティションは「期間削除が頻繁」「検索範囲が明確」なテーブルに限定して検討する
  • まずは月次ログなど適用条件が明確なテーブルから始める
  • DROP PARTITION による高速削除はパーティションの最大のメリットなので積極的に活用する
  • WHERE句にパーティションキーを含めないと効果がないため、クエリパターンを先に確認する
  • 既存テーブルへの後付けは ALTER TABLE ... PARTITION BY で可能だが、大量データの場合はロック時間に注意する

次回は ビューとストアドプロシージャ を学びます。共通SQLをDB側で管理する方法と、その使い分けの判断基準を解説します。

Related Articles