【実務・中級編】 外部テーブルに対するインデックス – PostgreSQL

外部テーブルにインデックスが貼れない!その時、現場のエンジニアはどう立ち回るべきか?

やあ。最近、PostgreSQLの`postgres_fdw`(Foreign Data Wrapper)を使って、マイクロサービス間のデータ連携や、巨大なアーカイブテーブルの参照を実装しているプロジェクトが増えてきたよね。

便利な機能なんだけど、実務で触り始めると必ずと言っていいほどぶつかる壁がある。「外部テーブルに対してインデックスが作れない!」という問題だ。

「え、じゃあパフォーマンスはどうすればいいの? 全件スキャン走るの?」と不安になった君のために、今日は現場で役立つ、外部テーブルとインデックスの「付き合い方」を伝授するよ。

—

外部テーブルにインデックスが貼れない理由

まず基本のおさらいだけど、PostgreSQLの外部テーブルは、あくまで「窓口」に過ぎない。実データは別のサーバー(リモート)にあるわけだよね。

もしローカルのPostgreSQLで`CREATE INDEX`を叩こうとしても、エラーが返ってくるはずだ。理由は単純で、ローカルのPostgreSQLはリモート側のストレージに直接アクセス権を持っていないし、インデックスの整合性を担保する術がないからだ。

だから、「ローカルで頑張っても無駄」ということを、まずは肝に銘じておこう。

鍵は「リモート側」にある

じゃあ諦めるしかないのか? いや、違う。ここで視点を変えるんだ。「ローカルから投げたクエリが、リモートでどう実行されているか」を追跡する。

ヒントは `EXPLAIN` だ。

— ローカルで実行
EXPLAIN ANALYZE SELECT FROM foreign_table WHERE user_id = 123;

これを確認してほしい。もし実行計画の中に `Remote SQL: SELECT … WHERE user_id = 123` という行があれば、そのクエリはリモート側に丸投げされている。

この時、リモート側のテーブルに `user_id` に対するインデックスが張られていれば、リモート側で高速に検索が実行されるんだ。つまり、ローカルでインデックスを貼る必要なんてない。リモートのテーブルが適切にインデックス化されていれば、外部テーブル経由でも爆速で結果が返ってくる。

実務で陥りがちな罠:フィルタ条件が漏れるとき

ここで一つ、現場でよくある失敗事例を紹介するよ。

「リモートにはインデックスを貼ったのに、なぜかクエリが遅い」というケースだ。よく見ると、ローカルで以下のようなことをしていないかな?

— ダメな例:関数を通すとインデックスが効かなくなる
SELECT FROM foreign_table WHERE lower(email) = ‘test@example.com’;

リモート側に `email` のインデックスがあっても、`lower()` をローカルで適用してしまうと、リモート側には「全件持ってきてから、ローカルでフィルタリングする」という実行計画が送られることがある。こうなると、リモートのインデックスは無力化されるんだ。

対策:
1. リモート側で関数インデックス(`CREATE INDEX ON table (lower(email))`)を作成する。
2. もしくは、検索条件を極力そのままリモートに送れる形(生のカラム指定)にする。

それでもパフォーマンスが出ない時の「最終兵器」

どうしてもリモート側のインデックスだけでは賄えない、複雑な結合や集計が必要な場合もあるよね。その時は、素直に方針転換しよう。

  • マテリアライズド・ビュー(Materialized View)の検討:

頻繁に参照するデータなら、外部テーブルを毎回叩くのではなく、定期的にローカルへ同期(同期用バッチを作成)して、ローカル側にテーブルを作ってしまう。インデックスも貼り放題だ。

  • WHERE句の工夫:

リモート側に送るパラメータを絞り込んで、リモート側の負荷を減らす。

—

まとめ:結局、どう設計すべきか?

現場のエンジニアとしてのアドバイスはこうだ。

1. 外部テーブルは「リモートのインデックス」を信じろ。 インデックス設計はリモート側で完結させる。
2. `EXPLAIN` を見て、リモートへ正しくクエリがプッシュダウンされているか確認しろ。
3. ローカルでの加工(関数適用など)は、リモートのインデックスを殺す可能性があると意識せよ。
4. 無理ならローカルにデータを持ってこい。 外部テーブルに過度な期待をしないのが、システムの安定稼働のコツだ。

PostgreSQLのFDWは非常に強力な武器だけど、魔法の杖じゃない。特性を理解して、泥臭く「リモート側のインデックス設計」に気を配る。これだけで、システムのパフォーマンスは劇的に変わるはずだよ。

また何か詰まったら、いつでも聞いてくれ。現場からは以上だ!

コメント

タイトルとURLをコピーしました