複合インデックスと列の順序
複合インデックスの列順を選び、左端プレフィックスルールを理解して、複数のクエリをカバーするインデックスを設計します。
「複合インデックスと列の順序」はCoddyKit上の無料SQL Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSQL Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 SQL Academyコースには全4レッスンが含まれています。
複合インデックスとは
複数の列に対するインデックスです。PostgreSQL の B-tree では最大 32 列までインデックスを作成できますが、実際には 2〜4 列が一般的です。
CREATE INDEX orders_user_created_idx ON orders(user_id, created_at DESC);複合インデックスを使う理由
主なケースは 2 つあります。
- クエリが複数の列を同時に絞り込む場合
- クエリが 1 つの列で絞り込み、別の列でソートする場合
左端プレフィックスのルール
(a, b, c) に対するインデックスは、次のクエリに使用できます。
WHERE a = ?WHERE a = ? AND b = ?WHERE a = ? AND b = ? AND c = ?
WHERE b = ? 単独にも、WHERE c = ? にも使用できません。
順序が重要な理由
最も選択性が高く、かつ最も頻繁にフィルターされる列を先頭に置きます。等価条件の列を範囲条件の列より前に置きます。
CREATE INDEX orders_user_total_idx ON orders(user_id, total);
-- Best for: WHERE user_id = 42 AND total > 100
-- Also OK: WHERE user_id = 42
-- Useless: WHERE total > 100 (without user_id)等価条件と範囲条件
等価述語はインデックスを効率的に使用できます。範囲条件でも使用できますが、その後の活用範囲が制限されます。等価条件の列を先に置いてください。
-- Index: (status, created_at)
WHERE status = 'paid' AND created_at >= ... -- both columns used
WHERE created_at >= ... AND status = 'paid' -- index used for status, range scan on created_atインデックスの順序 = ソート順
(user_id, created_at DESC) に対するインデックスがあれば、「ユーザーの注文を新しい順に取得する」処理を、ソート手順なしで実行できます。
EXPLAIN ANALYZE
SELECT * FROM orders
WHERE user_id = 42
ORDER BY created_at DESC LIMIT 10;
-- Index Scan, no Sort node neededキー以外の列を含める(INCLUDE)
PG 11 以降では、「カバリング」インデックスのために INCLUDE を使用できます。追加の列はリーフに格納されますが、並び順には使用されません。
CREATE INDEX orders_user_idx ON orders(user_id)
INCLUDE (total, status);
-- Enables Index-Only Scan for queries that need just these columns.複合インデックスを作らない場合
列がそれぞれ独立して検索される場合は、単一列インデックスを 2 つ作る方が多くのクエリに対応できます。複合インデックスは柔軟性と引き換えに、「1 つのクエリに必要なものがすべてそろう」利点を得るものです。
ビットマップインデックスの組み合わせ
PostgreSQLでは、Bitmap Index Scanによって複数の単一列インデックスを組み合わせられます。
EXPLAIN ANALYZE
SELECT * FROM orders WHERE user_id = 42 AND status = 'paid';
-- BitmapAnd of two index scans — works without a composite, but slower than the right composite.インデックスの肥大化に注意
複合インデックスは幅が広くなります。幅が広いインデックス = ファイルが大きい = キャッシュに収まるインデックスの量が少ない、ということです。慎重に設計してください。
列の順序の選び方 — 実例
クエリ: 「あるユーザーの指定期間内の注文を、日付順に取得する」。
-- Index design:
CREATE INDEX orders_user_created_idx
ON orders(user_id, created_at DESC);
-- Query (efficiently uses the index):
SELECT * FROM orders
WHERE user_id = 42
AND created_at >= NOW() - INTERVAL '30 days'
ORDER BY created_at DESC LIMIT 10;まとめ
複合インデックスは複数列のフィルタに対応し、ソート処理を省略できます。
- 左端プレフィックスのルール
- 等価条件の列を先にする
- カバー専用の列にはINCLUDEを使う
- 単一列インデックス2つと複合インデックス1つのどちらがよいかは、クエリの構成による
理解度チェック
(user_id, status, created_at) に対するインデックスがあります。どのクエリでは、このインデックスを効率的に利用できませんか。
よくある質問
「複合インデックスと列の順序」レッスンは無料ですか?
はい。「複合インデックスと列の順序」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、SQL Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 SQL Academyコースには全4レッスンが含まれています。
「複合インデックスと列の順序」で何を学びますか?
複合インデックスの列順を選び、左端プレフィックスルールを理解して、複数のクエリをカバーするインデックスを設計します。 ブラウザで直接実行するハンズオンコードでSQL Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
SQL Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのSQL Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「複合インデックスと列の順序」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このSQL Academyレッスンでコードを書いて実行できますか?
はい。すべてのSQL Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。