データ量が数千万〜数億件を超えるような大規模システムでは、通常の設計手法では処理が追いつかないことがあります。本章では、PostgreSQLやRedshiftにおけるパーティション設計、分散処理のためのシャーディング、そして高速に大量更新を実現するバルク処理戦略について、実務ベースで解説します。
パーティション分割テーブルの設計(PostgreSQL / Redshift)
パーティショニングとは、1つの大規模テーブルを条件によって複数の物理パーツ(パーティション)に分割する設計手法です。
PostgreSQL:レンジパーティショニングの例
-- 親テーブル CREATE TABLE sales ( id SERIAL, sale_date DATE, amount NUMERIC ) PARTITION BY RANGE (sale_date); -- 子テーブル(2025年用) CREATE TABLE sales_2025 PARTITION OF sales FOR VALUES FROM ('2025-01-01') TO ('2026-01-01');
- 利点: 条件に合うパーティションだけをスキャンするため、クエリが高速化
- 注意点: パーティション条件(WHERE句)を明示するのがベストプラクティス
Amazon Redshift:DISTKEY / SORTKEY + 分割ロード戦略
RedshiftではPostgreSQLのようなパーティションは使えませんが、ソートキー(SORTKEY)と分散キー(DISTKEY)を工夫することで同様の効果が得られます。
CREATE TABLE sales ( sale_id INT, sale_date DATE, amount DECIMAL(10,2) ) DISTKEY(sale_id) SORTKEY(sale_date);
加えて、S3経由でのUNLOAD/ COPY + MANIFESTを使ったパーティション単位の外部ロードもパフォーマンスチューニングに効果的です。
シャーディングと水平分割の考え方
シャーディング(Sharding)は、テーブルのデータを複数の物理DBに分散して格納することで、スケーラビリティと可用性を高めるアーキテクチャ手法です。
水平分割(Horizontal Partitioning)
1テーブルの行データを「IDや地域コード」などで分割します。
-- 例:ユーザIDの末尾数字で分割 users_0:user_id % 10 = 0 users_1:user_id % 10 = 1 ... users_9:user_id % 10 = 9
実装方法
- アプリケーションでDB接続先を振り分ける
- 中間層(プロキシやORM)でルーティング
- オープンソースのツール例:
Citus(PostgreSQL拡張)、Vitess(MySQL向け)
注意: JOIN・集計などのクロスシャード処理が困難になるため、マスタデータの冗長配置や非正規化が必要なケースもあります。
大量データ更新時のバルク処理戦略
数百万件を一括でINSERT/UPDATE/DELETEする場合、単純なSQLでは処理時間が長く、ロックやタイムアウトが発生する恐れがあります。
バッチ処理(小分け更新)の設計
-- 例:1万件ずつDELETE DO $$ DECLARE deleted_rows INTEGER; BEGIN LOOP DELETE FROM logs WHERE created_at < NOW() - INTERVAL '6 months' LIMIT 10000; GET DIAGNOSTICS deleted_rows = ROW_COUNT; EXIT WHEN deleted_rows = 0; END LOOP; END $$;
このように小分け処理をループさせることで、トランザクションの肥大化を防止できます。
条件制御付きのバルクUPDATE
UPDATE orders SET status = 'expired' WHERE status = 'pending' AND order_date < CURRENT_DATE - INTERVAL '30 days' AND id BETWEEN 100000 AND 200000;
IDや日時範囲で分割することにより、インデックス活用を促し、ロック競合を回避できます。
高速ロード戦略(PostgreSQL / Redshift)
- PostgreSQL:
COPYコマンドで一括ロード - Redshift:
COPY FROM S3+ gzip圧縮 + 並列化 - 削除/更新ではなく差分INSERT+ビュー更新戦略(処理時間の短縮)
まとめ
大規模データ処理では、ボトルネックの回避とパフォーマンス維持のために、設計段階から以下を意識することが不可欠です。
- パーティション分割やSORTKEYを使ったクエリ高速化
- シャーディングを用いたスケーラブルな構造の構築
- バッチ分割や条件制御で安全な大量更新を実現
今後のデータ拡張やクラウド移行を見据え、最適化設計を意識した開発を行いましょう。

