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');

クエリが特定パーティションのみを読む(パーティションプルーニング)ことで大幅高速化できます。