既存Railsにpgvectorを導入する実装と運用の勘所
「RAGを実装したいのでPineconeかWeaviateを検討している」という相談を受けて、既存のPostgreSQLを見てみると、実はそのままpgvectorを載せるだけで要件を満たせるケースが少なくありません。専用ベクトルDBの検討に時間を使う前に、今動いているRailsとPostgreSQLで足りるかどうかを先に見るべきです。
この記事では、既存Railsアプリに実際にpgvectorを導入した経験をもとに、専用ベクトルDBとの選び方、実装で詰まりやすい点、導入後の運用でハマりやすい点を、発注者(CTO)向けに整理します。
専用ベクトルDBとpgvector、どちらを選ぶか
まず判断軸を明確にします。「新しいDBを増やすコスト」と「性能・機能の要件」のトレードオフです。
pgvectorを選ぶべきケース:
- 既存データ(ユーザー・商品・記事など)と同じトランザクション内でベクトル検索結果を使いたい(例: 「このユーザーが閲覧履歴のある商品カテゴリに近い商品を、在庫がある条件で検索」のようにRDBのJOIN・WHEREとベクトル距離を混ぜたいケース)
- 想定件数が数百万行規模まで(数千万を超えると専用DBの方が優位になりやすい)
- インフラ・監視・バックアップの運用対象を増やしたくない(既存のPostgreSQLの運用ノウハウをそのまま使える)
- PoCから始めて、必要になったら専用DBへ移行する余地を残したい
専用ベクトルDB(Pinecone、Weaviate、Qdrantなど)を選ぶべきケース:
- 数千万〜億件規模のベクトルを、低レイテンシで検索する必要がある
- マルチテナントでの厳密な分離やスケールアウトの運用実績を最初から求められている
- ベクトル検索がプロダクトの主機能で、専任チームが運用コストを負担できる
私たちの経験では、既存のRailsプロダクトに「検索を賢くしたい」「類似商品を出したい」「社内文書でRAGをやりたい」という後付け要件の8割方はpgvectorで足ります。専用DBは「移行してでも欲しい性能が明確にある」ときに検討すれば十分です。最初から専用DBを導入して、結局PostgreSQLとの二重管理・同期処理のコストだけが残るケースを何度か見てきました。
実装の勘所
埋め込みの生成と保存
埋め込み(embedding)はOpenAIの text-embedding-3-small(1536次元、または512次元に切り詰め可能)を使うのが実務上のデフォルトです。Railsでの実装は次の形になります。
# Gemfile
gem "pgvector"
gem "ruby-openai"
# migration
class AddEmbeddingToArticles < ActiveRecord::Migration[7.0]
def change
enable_extension "vector" unless extension_enabled?("vector")
add_column :articles, :embedding, :vector, limit: 1536
end
end
次元数は後から変えられないことに注意してください。埋め込みモデルを変更・アップグレードする場合、カラムの再作成とデータの全件再生成が必要になります。最初にモデルを固定し、次元を絞りたい場合は生成時にAPI側で指定するのが安全です(例: text-embedding-3-large を256次元に切り詰めるより、text-embedding-3-small をそのまま使う方が運用がシンプル)。
埋め込みの生成は同期処理に混ぜず、必ず非同期ジョブ(Sidekiqなど)に切り出します。埋め込みAPIは1件あたり数百ms〜数秒かかることがあり、保存処理と直列にすると通常のCRUDが遅延します。既存の after_commit フックでジョブをenqueueし、本文(title・description等)の変更があったときだけ再生成する差分制御を入れないと、無関係な更新のたびにAPIコストが発生します。
インデックス種別: HNSW か IVFFlat か
pgvectorには近似最近傍探索用のインデックスが2種類あります。結論から言うと、新規導入では基本的にHNSWを選んでください。
| HNSW | IVFFlat | |
|---|---|---|
| 検索精度・速度 | 高い、更新に強い | やや劣る、クラスタ数の調整が要る |
| インデックス構築時間 | 長い(データ量に比例して伸びる) | 短い |
| データ追加への耐性 | 追加ごとに再構築不要 | 大量追加後は再構築(REINDEX)推奨 |
| メモリ使用量 | 大きめ | 小さめ |
IVFFlatは「事前にクラスタ数(lists)を決め打ちする」性質上、データ件数が想定と大きくズレると精度が落ちます。運用中にデータが増減する一般的なプロダクトでは、この前提が崩れやすく、定期的なREINDEXが実質必須になります。HNSWは追加のたびに再構築が要らないため、通常のRailsアプリの運用サイクル(日次でレコードが増える等)と相性が良いです。
# HNSWインデックスの例(コサイン距離)
add_index :articles, :embedding, using: :hnsw, opclass: :vector_cosine_ops
距離関数は埋め込みモデルの想定に合わせます。OpenAIのembeddingはコサイン距離(vector_cosine_ops)が標準です。内積(vector_ip_ops)やユークリッド距離(vector_l2_ops)を使う必要があるのは、埋め込みが正規化されていない自前モデルなど限定的なケースに限られます。ここを混同すると、検索結果の並び順が体感的におかしくなります。
既存DBへの後付けで気をつける点
- 本番のマイグレーションでインデックス構築がロックを取る。
CREATE INDEXは対象テーブルへの書き込みをブロックするため、行数が多いテーブルではalgorithm: :concurrently(HNSWは対応、IVFFlatも対応)を使い、トランザクション外で実行する - 既存テーブルに直接カラムを足すか、別テーブル(
article_embeddings)に切り出すかは、そのカラムがどれだけ頻繁に全件スキャンされるかで決める。他の集計クエリでSELECT *が多いテーブルなら、1536次元(float4で約6KB/行)のvectorを混ぜるとI/Oが増えるため別テーブルに逃がす判断も検討する - 既存のPostgreSQLのバージョンを確認する。pgvectorはPostgreSQL 13以上が必要で、HNSWインデックスはpgvector 0.5.0以降。マネージドDB(RDS、Cloud SQLなど)を使っている場合は、拡張機能として有効化できるバージョンかを事前に確認する
運用: 再インデックス・パフォーマンス・コスト
導入後に発生する運用コストを事前に見積もっておくと、後から「思ったより高い」という驚きを避けられます。
- 埋め込みAPIのコスト:
text-embedding-3-smallは1Mトークンあたり数十円程度と安価ですが、既存データ全件の初回生成(バックフィル)は件数によっては数千円〜数万円規模になる。プロダクトの成長に応じて継続的に発生する費用としても、月次のレコード増加数から概算しておく - 検索速度の実測: HNSWでも、
ef_searchパラメータ(検索時の探索幅)を上げるほど精度は上がるがレイテンシも増える。デフォルト値のまま本番投入せず、実データでEXPLAIN ANALYZEを取って許容レイテンシに収まるか確認する - フィルタ付き検索の落とし穴: 「カテゴリXの中で類似検索」のようにWHERE句と組み合わせると、pgvectorのインデックスが使われずシーケンシャルスキャンに落ちることがある。実行計画を確認し、必要なら部分インデックスや事前フィルタリングの設計を見直す
- バックアップとレプリケーション: vector型のカラムは通常のPostgreSQLバックアップ(pg_dump、WALベースのレプリケーション)にそのまま乗る。専用ベクトルDBのような別立てのバックアップ運用を新たに組む必要がない、というのはpgvectorを選ぶ実務上のメリットの一つ
キーワード検索とのハイブリッド構成(全文検索とベクトル検索を組み合わせてスコアリング)を検討している場合は、既存プロダクトにAI検索を後付けする進め方で具体的な設計パターンを解説しています。
外注時の進め方
pgvector導入を外部チームに依頼する場合、いきなり全文書のベクトル化とRAG構築を頼むのではなく、次の順序を推奨します。
- 小さいデータセットでのPoC(1〜2週間): 実際のデータの一部で埋め込み生成・検索精度を検証し、期待する検索体験が出るか確認する
- 本番スキーマへの組み込みとインデックス設計: HNSW/IVFFlatの選定、既存テーブルへの影響範囲の洗い出し
- バックフィルジョブとコスト試算: 全件の埋め込み生成にかかる時間とAPIコストを見積もり、本番投入のタイミングを決める
- 監視の組み込み: 検索レイテンシとAPIコストを継続的に見える化する
改善の前提として、そもそも今のプロダクトがこうした変更を安全に受け入れられる状態かは、既存プロダクトの改善、外部チームが最初に見る観点で整理しています。
まとめ
- 既存Railsプロダクトへのベクトル検索導入は、多くの場合専用ベクトルDBを増やさずpgvectorで足りる。判断軸は件数規模と「既存データとJOINしたいか」
- 実装ではHNSWインデックス・コサイン距離・非同期での埋め込み生成が基本形。次元数は後から変更できない点に注意する
- 運用ではAPIコスト・検索レイテンシの実測・フィルタ付き検索でのインデックス退避を事前に見積もっておくことが、導入後の驚きを防ぐ
torcheeesはRuby on Rails・PostgreSQL(pgvector)・OpenAI/Claude APIの組み合わせで、既存プロダクトへのAI機能後付けを数多く手がけています。AI導入・活用支援やデータベース設計・改善の一環として、要件整理から実装・運用まで伴走可能です。まずは1〜4週間の「開発診断」で現状のDB構成と実現可能性を確認するか、継続的な改善支援でそのまま実装まで進めることもできます。お問い合わせフォームからご相談ください。