千万件規模データを処理するMySQLサーバの構築とチューニング

インフラリソースの選定基準

データ規模が千万件レベルに達すると、ストレージI/Oおよびメモリ割り当てが性能の主要なボトルネックとなります。計算処理を分散させるためのマルチコアCPU、InnoDBバッファプールを物理メモリ容量の60〜70%確保するための大容量RAM、および低レイテンシNVMe SSDの採用が基盤構築の前提条件となります。

構成パラメータの最適化

MySQLの動作定義は通常 /etc/mysql/mysql.conf.d/mysqld.cnf に格納されています。権限昇格後にエディタで対象ファイルを開き、[mysqld] セクション内の数値を環境に合わせて上書きします。

sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf

以下のディレクティブは、メモリキャッシュの拡張と同時接続スレッドの増強を目的とした設定例です。

[mysqld]
# InnoDB用メモリプール割り当て
innodb_buffer_pool_size = 16G

# スレッドプールによる同時接続上限
max_connections = 3000

# ディスクI/Oフラッシュ頻度の制御(耐久性と速度のバランス調整)
innodb_flush_log_at_trx_commit = 2

# テンポラリテーブルのメモリ閾値引き上げ
tmp_table_size = 256M
max_heap_table_size = 256M

保存終了後、systemctl restart mysql を実行して構成をリロードします。

インデックス戦略の見直し

大規模テーブルにおけるフルスキャンは応答遅延を招きます。WHERE句や結合条件で頻繁に評価されるカラムに対して、複合B-Treeインデックスを適用することで走査範囲を限定します。

ALTER TABLE access_records 
ADD INDEX idx_status_time (request_status, logged_at DESC);

最左接頭辞の原則に準拠したカラム順序でインデックスを定義することで、クエリプランナが効率よくインデックスレンジスキャンを選択するようになります。

データ分割によるI/O負荷分散

単一物理ファイルの肥大化はメンテナンスコストとロック競合を悪化させます。論理的な区切り(例:作成日時や拠点コード)に基づいてデータを物理的に分離するレンジパーティショニングが有効です。

CREATE TABLE system_events (
    event_id BIGINT NOT NULL AUTO_INCREMENT,
    occurred_at DATETIME NOT NULL,
    severity_code TINYINT,
    payload TEXT,
    PRIMARY KEY (event_id, occurred_at)
) ENGINE=InnoDB
PARTITION BY RANGE (YEAR(occurred_at)) (
    PARTITION p_2021 VALUES LESS THAN (2022),
    PARTITION p_2022 VALUES LESS THAN (2023),
    PARTITION p_2023 VALUES LESS THAN (2024),
    PARTITION p_current VALUES LESS THAN MAXVALUE
);

InnoDBエンジンではパーティションキーを主キーに含める必要があるため、occurred_at を複合主キーに追加しています。この構造により、過去のデータ削除が ALTER TABLE system_events DROP PARTITION p_2021; のメタデータ操作のみで瞬時に完了し、バックグラウンドのI/O負荷を最小限に抑えられます。

タグ: mysql-tuning innodb-configuration range-partitioning query-optimization composite-index

6月7日 21:30 投稿