SQLが遅くなる主な原因
大量データを扱うデータベースでは、設計の工夫次第でクエリの実行速度が100倍以上変わることがあります。パフォーマンス改善の出発点は「実行計画(EXPLAIN)を読む」ことです。
EXPLAINの読み方
EXPLAIN ANALYZE SELECT * FROM orders
WHERE customer_id = 12345 AND status = 'pending';
出力のSeq Scan(フルスキャン)は要注意。Index Scanになっているかを確認します。
インデックスの基本
-- インデックスなし:100万行フルスキャン
SELECT * FROM orders WHERE customer_id = 12345;
-- インデックス追加後
CREATE INDEX idx_orders_customer ON orders(customer_id);
-- 実行時間が100ms → 1ms以下に改善することも
よくある最適化パターン
| アンチパターン | 改善策 |
|---|---|
SELECT * |
必要なカラムのみ指定 |
LIKE '%keyword%' |
全文検索エンジン(Elasticsearch)を検討 |
| N+1クエリ | JOINまたはサブクエリで1回に |
| 関数でラップしたカラムでのWHERE | 計算済みカラム or 関数インデックス |
| ループ内でのINSERT | バルクINSERT |
複合インデックスの設計
-- WHERE customer_id = ? AND status = ? ORDER BY created_at
-- に対する最適なインデックス
CREATE INDEX idx_customer_status_date
ON orders(customer_id, status, created_at);
-- カーディナリティの高いカラムを先頭に
パーティショニング
数億行を超えるテーブルはパーティショニングで物理分割します。
CREATE TABLE orders_2024 PARTITION OF orders
FOR VALUES FROM ('2024-01-01') TO ('2025-01-01');
クエリが特定パーティションのみを読む(パーティションプルーニング)ことで大幅高速化できます。





