インデックスのメンテナンスと肥大化
インデックスの肥大化を診断し、REINDEX CONCURRENTLYで再構築して、未使用のインデックスを安全に削除します。
「インデックスのメンテナンスと肥大化」はCoddyKit上の無料SQL Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSQL Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 SQL Academyコースには全4レッスンが含まれています。
インデックスが肥大化する理由
PostgreSQLはMVCCを使用します。UPDATEによって新しい行バージョンが書き込まれ、既存のトランザクションから見えている古いバージョンは残ります。両方のバージョンに対するインデックスエントリが存在するため、時間の経過とともに次のようになります。
- 更新の多いテーブルでは、不要になったインデックスエントリが蓄積する
- インデックスが必要以上に大きくなる
- B-treeが深くなり、検索が遅くなる
肥大化の診断
肥大化を確認するクエリは単純ではありません。一般的なツールには次のものがあります。
pgstattuple拡張- pg_repackのレポート
- check_postgresや監視ツールが提供する肥大化確認クエリ
CREATE EXTENSION pgstattuple;
SELECT * FROM pgstatindex('orders_user_id_idx');REINDEX
インデックスを再構築します。従来の形式ではACCESS EXCLUSIVEロックを取得するため、本番環境には適していません。
REINDEX INDEX orders_user_id_idx; -- blocks writes!REINDEX CONCURRENTLY (PG 12以降)
ブロックを抑えた方式です。再構築中も読み取りと書き込みを継続できます。
REINDEX INDEX CONCURRENTLY orders_user_id_idx;未使用のインデックス
未使用のインデックスは、すべての書き込みを遅くする一方で、読み取りを1回も高速化しません。次の方法で見つけられます。
SELECT schemaname, relname, indexrelname, idx_scan, pg_size_pretty(pg_relation_size(indexrelid))
FROM pg_stat_user_indexes
WHERE idx_scan = 0
AND indexrelname NOT LIKE '%_pkey'
ORDER BY pg_relation_size(indexrelid) DESC;未使用のインデックスを削除する
削除する前に、すべての環境と時間帯をまたいで確認してください。たまにしか実行しないレポート用のインデックスは、ほとんどの時間帯で未使用に見えます。
DROP INDEX CONCURRENTLY old_unused_idx;重複するインデックス
制約と手動のCREATE INDEXによって、同じインデックスが作成されていることがあります。pg_indexesで重複を確認し、不要な方を削除してください。
SELECT tablename, indexname, indexdef
FROM pg_indexes
WHERE schemaname = 'public'
ORDER BY tablename, indexname;インデックスによる書き込み増幅
INSERT/UPDATE/DELETEを実行するたびに、関連するすべてのインデックスが更新されます。更新の多いテーブルにインデックスが3つあると、書き込みコストは3倍になります。効果のあるインデックスだけを追加してください。
GINの保留リスト
GINインデックスは、保留リストに更新をまとめて保存します。手動でフラッシュするか、autovacuumに任せます。
SELECT gin_clean_pending_list('events_data_gin');VACUUMによるインデックスエントリのクリーンアップ
VACUUM(MVCCのレッスンで説明します)は、ヒープページから不要になったインデックスエントリを削除します。autovacuumがなければ、インデックスは際限なく大きくなります。
インデックスサイズの監視
時間の経過に伴うインデックスサイズを追跡します。
SELECT pg_size_pretty(pg_indexes_size('orders')) AS index_size,
pg_size_pretty(pg_total_relation_size('orders')) AS total_size;pg_repack: テーブルをオンラインで書き換える
肥大化が深刻な場合、pg_repackはテーブルとインデックスをオンラインで書き換えます。テーブル全体をロックする必要はありません。OSパッケージとPostgreSQL拡張としてインストールします。
まとめ
インデックスにはメンテナンスが必要です。
- MVCCによる肥大化は正常な現象です。VACUUMとREINDEX CONCURRENTLYで管理してください
- 未使用のインデックスを削除する
- 重複を避ける
- 新しいインデックスを追加するたびに書き込みは遅くなるため、慎重に判断する
理解度チェック
書き込みをブロックせずにインデックスを再構築するPostgreSQLコマンドはどれですか。
よくある質問
「インデックスのメンテナンスと肥大化」レッスンは無料ですか?
はい。「インデックスのメンテナンスと肥大化」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、SQL Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 SQL Academyコースには全4レッスンが含まれています。
「インデックスのメンテナンスと肥大化」で何を学びますか?
インデックスの肥大化を診断し、REINDEX CONCURRENTLYで再構築して、未使用のインデックスを安全に削除します。 ブラウザで直接実行するハンズオンコードでSQL Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
SQL Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのSQL Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「インデックスのメンテナンスと肥大化」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このSQL Academyレッスンでコードを書いて実行できますか?
はい。すべてのSQL Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- B-tree、Hash、GiST、GINインデックス
- 複合インデックスと列の順序
- 部分インデックスと式インデックス
- インデックスのメンテナンスと肥大化