部分インデックス

   ここまでに紹介したインデックスは、あるテーブルのある列(もしくは列の組み合わせ)に関するすべての行のデータをインデックス化するものでした。 しかし、頻繁に検索される値の範囲が決まっている場合は、その範囲を指定することによって、一部の行のみをインデックス化した部分インデックス (partial index)を作ることができます。部分インデックスはデータ量が少ないため、ディスクスペースを浪費しないだけでなく、検索効率も優れています。

   たとえば、売上データを管理するテーブルがあり、売上高の高いものを頻繁に検索する場合には、次のようにCREATE INDEX文の最後にWHERE句で条件を指定して、条件にマッチするデータだけがインデックスに格納されるようにします。
 

CREATE INDEX salesindex ON sales (amount) WHERE amount > 10000;

   この部分インデックスは下記には適用されます。



SELECT * FROM sales WHERE amount > 10000;

SELECT * FROM sales WHERE amount > 20000;

   しかし、下記には適用されません。



SELECT * FROM sales WHERE amount > 5000;

   検索値に部分インデックスの範囲外の値が含まれるからです。

インデックスが使われているかどうかを判断する

   実際にインデックスが使われているかどうかを判断する一番簡単な方法はEXPLAINを使うことです。EXPLAINはもともとPostgreSQLの問い合わせオプティマイザが生成した問い合わせプランを検証するためのコマンドです。

   通常、PostgreSQLは最も適切な(言い換えると最も高速な)問い合わせプランを作成してくれるのですが、この問い合わせプランは常に完璧と いうわけではありません。何らかの理由で不適切な問い合わせプランを作成してしまうこともあります。インデックスを作成したのに効率が向上しない場合は、 EXPLAINを使って問い合わせプランを確認してみるとよいでしょう。

   EXPLAINの使い方は簡単です。通常のSQL文の前に「EXPLAIN」と入れるだけです。図6を参照してください。

 

test=# EXPLAIN SELECT * FROM accounts WHERE aid = 1;

QUERY PLAN
---------------------------------------------------------------------
 Index Scan using accounts_pkey on accounts (cost=0.00..3.01 rows=2 width=100)
   Index Cond: (aid = 1)
(2 rows)

図6:EXPLAINの使用例1

   「Index Scan using〜」とあるので、実際にインデックスが使われていることがわかります。使われているのはaccounts_pkeyです。これは、図7を見るとわかるようにaid列に自動的に作られた主キー制約用のインデックスです。


test=# \d accounts
Table "public.accounts"
Column|Type|Modifiers
−−−−−−−−−+−−−−−−−−−−−−−−+−−−−−−−−−−
aid|integer|not null
bid|integer|
abalance|integer|
filler|character(84)|
Indexes:
"accounts_pkey" primary key, B-tree (aid)

図7:accountsテーブルのインデックス

   逆にインデックスが使われないケースも見てみましょう(図8)。
 

test=# EXPLAIN SELECT count(*) FROM accounts;
QUERY PLAN
---------------------------------------------------------------------
Aggregate (cost=2890.00..2890.00 rows=1 width=0)
 ->Seq Scan on accounts (cost=0.00..2640.00 rows=100000 width=0)
(2 rows)

図8:EXPLAINの使用例2

   「Seq Scan」とはsequential scanの略で、順スキャン、すなわちテーブルを頭から順番に見ていく処理を表しています。当然ながら順スキャンは高速とはいえませんが、count() を行うには順スキャン以外に方法がないので、処理を改善する余地はありません。

人気記事トップ10

人気記事ランキングをもっと見る

企画広告も役立つ情報バッチリ! Sponsored

ClickHouse Cloudが実現した広告運用SaaS「ATOM」のデータ基盤革新、パフォーマンスを向上しながら、運用負荷とコストを削減 11月11日 6:20 AIで開発が加速する時代、品質保証はどう変わる? Tricentisが示すAIエージェント活用の実像 11月9日 6:45 悪用までの猶予が「1分」に迫るフロンティアAI時代に開発と本番を貫く脆弱性管理が必要 10月29日 8:30 欧州CRA対応とSBOM運用。AI生成コードのOSS混入問題の対策とは ――スニペット単位で検出する「FossID」「Insignary Clarity」によるSBOM運用 9月16日 6:40 PostgreSQLからTiDBへ、稼働中SaaSで進める段階的DB移行の実践と再設計への展望 9月7日 6:30 機能安全開発におけるGoogleTestの活用を支援!「Parasoft C/C++test CT」で実現する効率化&AI連携 4月14日 6:30 【CNDW2025】Grafanaが明かす「オブザーバビリティの哲学」ー最小限の労力で実用的なインサイトを得るには 1月23日 6:30 【CNDW2025】プロダクト急増に備える基盤刷新 ーウェルスナビがECSからEKSへの移行で得た知見とは 1月15日 6:30 【CNDW2025】250環境を5人で運用、構築時間は30分に ーKINTOテクノロジーズが語るインフラ基盤組織の作り方 2025年12月18日 6:30 新たな自動化で熱視線! AIエージェントの「推論能力」を支える2つのコンポーネントとは? 2025年11月28日 6:30