インデックスとは
データベース(PostgreSQL)のINDEXは、本の索引と同じようなものです。
検索を速くするため、INDEXの項目に対し、順に並べています。
「あ、い、え、お」というインデックスがあり、
そこに「う」を追加すると、「い」と「え」の間に「う」が入り、
「あ、い、う、え、お」となります。
インデックスの断片化
インデックスは B*Treeという木構造になっており、
最下層をリーフ(葉)と呼びますが、各リーフは容量制限があるため、
「あ、い、え、お」の状態でリーフが一杯になっていたら、
これ以上入らないため、「う」を登録する際、リーフが2つに分割されます。
これがインデックスの断片化になり、
進んでいくと、インデックスのサイズが大きくなっていくため、
そのインデックスが使われる可能性が低くなっていきます。
こうなるとシステムが遅くなりますが、
運用でインデックスの状態を確認していないと、遅い原因が全く分からず、
原因を特定するまでにかなりの時間がかかり、
対策にもかなりの時間がかかってしまうと思います。
インデックスの再構築
そのため、運用でインデックスの状態を監視し、
インデックスを定期的に再構築することが必要です。
PostgreSQLの場合、pgstatindexを実行して、インデックス断片化の状況を確認します。
が、注意点があります。
以下の2つの項目がありますが、「リーフページの断片化」と思いがちですが、
この値は間違えているので、「リーフページの平均密度」の値で判断する必要があります。
・avg_leaf_density :リーフページの平均密度
・leaf_fragmentation:リーフページの断片化
もう1点注意点があります。
「リーフページの平均密度」だけで判断してはいけません。
PostgreSQLの場合、8KB毎に作成されていくため、
データが1件しかないと、この値が低くなってしまうからです。
そのため、インデックスのサイズとリーフページの平均密度の
2つで判断する必要があります。
とは言え、このリーフページの平均密度ってどれくらいなの?
というのが、判断が難しいと思います。
私は 以下のように行っていました。
平均密度が50%超~70%位になったらインデックスを再構築する。
※50%だとなかなか達しないこともあると思うので、50%を超えた値にすると良いです。
【目安】
50%:INDEX再構築が難しい場合(仕組み的、タイミング的に)、INDEXスキャン回数が少ない [※]
70%:INDEX再構築が簡単にできる場合(仕組み的、タイミング的に)、INDEXスキャン回数が多い [※]
[※] pg_stat_user_indexes.idx_scan でスキャン累計回数を確認可能
この辺りの話は、以下のブログにまとめておりますので、是非参考にしてみて下さい。
PostgreSQL 纏め
https://chakugan.hatenablog.com/entry/2021/12/31/140837
補足(より深く学びたい方へ)
今回のような「性能問題の原因分析」や、
実務での運用・チューニング手順について、講座で体系的に解説しています。
※現在Udemyセール中のため、通常より安く受講できます。(残り1日)
https://www.udemy.com/course/postgresql-sql/?referralCode=64B372729B6BC0073ACB