KDOC 500: Covering Indexを試す
この文書のステータス
- 作成
- 2025-12-16 貴島
- レビュー
- 2025-12-16 貴島
概要
「Postgres で試した?」と聞き返せるようになるまでもしくはなぜ私は雰囲気で技術を語るのか?で、Covering Indexという見慣れない単語を見た。調べて、試す。
インデックスにINCLUDEオプションをつけることで、内容についてもキャッシュを追加できる。
オプションのINCLUDE句は非キー列としてインデックスに含める列のリストを指定します。 非キー列をインデックススキャンの検索条件に使うことはできません。また、インデックスで何であれ一意性制約や排他制約を強制する目的に対しても無視されます。 しかしながら、インデックスオンリースキャンは、インデックスエントリから値を直接得ることができるので、インデックスのテーブルを見に行く必要なく、非キー列の内容を返すことができます。 このように非キー列の追加は、そうでないとできないインデックスオンリースキャンを利用可能にします。 CREATE INDEX
CREATE TABLE users (
tel integer,
name1 varchar(255),
name2 varchar(255)
);
CREATE INDEX idx_users_name1 ON users(name1) INCLUDE (tel);
CREATE INDEX idx_users_name2 ON users(name2);
-- include付き。Index Only Scan
explain
select tel from users where name1 = 'a';
-- includeなし。Index Scan
explain
select tel from users where name2 = 'a';
| |
|----------------------------------------------------------------------------------|
| > CREATE TABLE users ( |
| > tel integer, |
| > name1 varchar(255), |
| > name2 varchar(255) |
| > ); |
| CREATE TABLE |
| |
| > CREATE INDEX idx_users_name1 ON users(name1) INCLUDE (tel); |
| CREATE INDEX |
| |
| > CREATE INDEX idx_users_name2 ON users(name2); |
| CREATE INDEX |
| |
| > explain |
| > select tel from users where name1 = 'a'; |
| QUERY PLAN |
| Index Only Scan using idx_users_name1 on users (cost=0.14..8.16 rows=1 width=4) |
| Index Cond: (name1 = 'a'::text) |
| |
| > explain |
| > select tel from users where name2 = 'a'; |
| QUERY PLAN |
| Index Scan using idx_users_name2 on users (cost=0.14..8.16 rows=1 width=4) |
| Index Cond: ((name2)::text = 'a'::text) |
関連
抽象。
- 検索に使わない値も索引に添えておくと、本体を見に行かずに済む
関連。
- 類推: KDOC 497: 複合インデックスの使用条件を試す。同じくインデックスの話題
- 具体例: どういったユースケースでCovering Indexを使うべきなのか
- 前提: KDOC 496: Index (Only) Scanの様子を見る。索引だけで必要な列が揃うと本体を読まずに済む仕組み