PostgreSQLでインデックスを削除したり変更したりする必要がある場面はいくつかあるんだ:
- インデックスの冗長性: インデックスを作りすぎて、もう使ってない場合、
INSERT、UPDATE、DELETEみたいな書き込み操作が遅くなることがあるよ。 - インデックスの破損: システム障害やPostgreSQLの異常終了の後で、インデックスが壊れることがある。
- 最適化: クエリにもっと合ったインデックスタイプがあると分かったら、既存のインデックスを置き換えたくなるよね。
- テーブル構造の変更: テーブルにカラムを追加・削除したとき、そのカラムに依存してるインデックスが不要になることがある。
これから、インデックス管理に役立つDROP INDEXとREINDEXコマンドの使い方を見ていこう。
DROP INDEXでインデックスを削除する
DROP INDEXコマンドは、データベースからインデックスを削除するために使うよ。基本の構文はこんな感じ:
DROP INDEX [ IF EXISTS ] index_name [ CASCADE ];
詳しく見てみよう:
IF EXISTS: 指定した名前のインデックスが存在しない場合でもエラーにならず、PostgreSQLは警告だけ出すよ。index_name: 削除したいインデックスの名前。CASCADE: インデックスに依存してるオブジェクトも一緒に削除する。これはあまり使わないけど、インデックスに依存関係がある場合に必要になることがある。
例1: シンプルなインデックス削除
例えば、studentsテーブルのemailカラムにインデックスがあって、もう不要になったとしよう。削除するにはこう書く:
DROP INDEX idx_students_email;
ここでidx_students_emailはインデックス名。実行するとインデックスがデータベースから消えるよ。
例2: 存在チェック付きでインデックス削除
インデックスが存在するか自信がないときは、IF EXISTSを使おう:
DROP INDEX IF EXISTS idx_students_email;
インデックスがなければ、PostgreSQLはエラーを出さずに警告だけ返すよ。
例3: 依存オブジェクトも削除(CASCADE)してみる
例えば、何か制約に紐づいたインデックスがある場合。例えばUNIQUE制約用に自動生成されたユニークインデックスとか。こういうインデックスを削除しようとすると、CASCADEを指定しないとPostgreSQLは許してくれない:
DROP INDEX idx_students_email CASCADE;
このやり方は慎重に使ってね。依存関係をちゃんと理解してからじゃないと、思わぬ影響が出るかも。
REINDEXでインデックスを再作成・修復する
REINDEXコマンドは、インデックスが壊れたり古くなったときに再作成するために使うよ。ファイルシステムのエラーやDB障害、長期間の運用でこういうことが起きるんだ。
基本構文
REINDEX { INDEX | TABLE | SCHEMA | DATABASE } name;
オプションを詳しく見ると:
INDEX: 特定のインデックスだけ再作成する。TABLE: 指定したテーブルの全インデックスを再作成する。SCHEMA: 指定したスキーマ内の全テーブルのインデックスを再作成する。DATABASE: 現在のデータベース内の全インデックスを再作成する。
例1: 特定インデックスの再作成
idx_students_emailインデックスの動作が遅いと感じたら、こうやって再作成できる:
REINDEX INDEX idx_students_email;
例2: テーブルの全インデックスを再作成
studentsテーブルのインデックスが壊れてパフォーマンスが落ちてるかも、と思ったら全部再作成しよう:
REINDEX TABLE students;
例3: データベース全体のインデックスを再作成
システム障害でデータベース全体のインデックスが壊れた場合、こうやって全部再作成できる:
REINDEX DATABASE university;
注意: このコマンドを実行するにはスーパーユーザー権限が必要だよ。
DROP INDEXとREINDEXを使うときのコツ
特に自動化スクリプトとか複雑な運用では、エラーを避けるためにIF EXISTSを使うのがオススメ。
インデックスを消す前に、本当に使われてないか確認しよう。インデックスが使われてるか調べるには、こんなクエリを実行してみて:
SELECT *
FROM pg_stat_user_indexes
WHERE indexrelname = 'idx_students_email';
CASCADEオプションは要注意!依存してる制約やオブジェクトがデータの整合性に大事なこともあるからね。
定期的なDBメンテナンスにはREINDEXを使おう。特に更新が多いテーブルや大量データを扱う場合に効果的だよ。
よくあるエラー
インデックスの削除や変更でよく出るエラーを紹介するね。
存在しないインデックスを削除しようとした場合。 IF EXISTSを使わないと、PostgreSQLはこんなエラーを出す:
ERROR: index "idx_nonexistent" does not exist
システムインデックスの削除。 間違ってシステムインデックスを消そうとすると大変なことになる。例えば、主キーみたいな重要なカラムには関連インデックスがあるけど、それは直接消せない。PostgreSQLはALTER TABLE DROP CONSTRAINT経由でしか消させてくれないよ。
テーブルのロック。 DROP INDEXやREINDEXの操作中に、テーブルがロックされることがある。特に同時に他のクエリが走ってるときは注意。ロックを避けたいなら、REINDEXの代わりにCONCURRENTLYオプション付きでインデックスを作り直すのもアリ。
実際のプロジェクトでの使い方
クエリ最適化: もう使ってないインデックスを見つけたら、DBリソースを節約するために削除しよう。
インデックスの掃除: 開発中に実験用で作った「ゴミ」インデックスが残ることがあるから、不要なものは定期的に消そう。
パフォーマンス維持: REINDEXでインデックスを再作成して、常に速く正しく動くようにしよう。
これらのツールを使えば、インデックスの作成だけじゃなく、効率的な管理もできるようになるよ。データベースの最適化とパフォーマンス維持にはインデックス管理が超大事。インデックスをちゃんと整理しておこう!
GO TO FULL VERSION