pgvector
作成日:
PostgreSQL vector-search database machine-learning
概要
pgvectorは、PostgreSQLでベクトル(埋め込み / Embedding)を保存し、類似性検索を行うための拡張機能です。AIや機械学習アプリケーションでセマンティック検索(意味的な検索)を実現するために使用されます。
pgvectorの特徴:
- PostgreSQLの拡張機能として動作
- ベクトルデータ型と類似性検索演算子を提供
- 既存のPostgreSQLインフラに統合可能
- Supabase、Amazon RDS、Cloud SQLなど主要なマネージドサービスでサポート
ベクトル検索の基礎概念については 検索技術の基礎 を参照。
なぜpgvectorを使うのか?
専用ベクトルDBとの比較
| 観点 | pgvector | 専用ベクトルDB(Pinecone等) |
|---|---|---|
| 学習コスト | PostgreSQLの知識で対応可能 | 新しいAPI・概念の学習が必要 |
| 運用 | 既存のPostgreSQL運用に統合 | 別途運用が必要 |
| コスト | PostgreSQLのコストのみ | 追加のサービス料金 |
| スケーラビリティ | 中規模まで(数百万ベクトル) | 大規模対応(数十億ベクトル) |
| 機能 | 基本的な類似性検索 | 高度なフィルタリング、メタデータ管理 |
pgvectorが適しているケース:
- 既存のPostgreSQLを使用している
- ベクトル数が数百万件以下
- シンプルな類似性検索で十分
- 追加のインフラを増やしたくない
専用ベクトルDBが適しているケース:
- 数十億規模のベクトル
- 高度なフィルタリングが必要
- 超低レイテンシが求められる
基本的な使い方
拡張機能の有効化
-- pgvector拡張を有効化
CREATE EXTENSION IF NOT EXISTS vector;
テーブルの作成
-- ベクトルカラムを持つテーブルを作成
CREATE TABLE articles (
id SERIAL PRIMARY KEY,
title TEXT NOT NULL,
content TEXT NOT NULL,
embedding VECTOR(1536) -- OpenAI text-embedding-3-small の次元数
);
VECTOR(n) の n は埋め込みモデルの次元数に合わせます:
| モデル | 次元数 |
|---|---|
| OpenAI text-embedding-3-small | 1536 |
| OpenAI text-embedding-3-large | 3072 |
| OpenAI text-embedding-ada-002 | 1536 |
| Cohere embed-multilingual-v3.0 | 1024 |
| intfloat/multilingual-e5-large | 1024 |
データの挿入
-- ベクトルデータを挿入
INSERT INTO articles (title, content, embedding)
VALUES (
'Dockerの基本',
'Dockerはコンテナ仮想化のプラットフォームです...',
'[0.1, 0.2, 0.3, ...]'::vector -- 実際には1536次元のベクトル
);
類似性検索
pgvectorは3種類の距離関数を提供します:
| 演算子 | 距離関数 | 説明 |
|---|---|---|
<-> | L2距離(ユークリッド距離) | 幾何学的な距離 |
<#> | 内積の負値 | 正規化されたベクトル向け |
<=> | コサイン距離 | 方向の類似性(最も一般的) |
-- コサイン距離で類似検索(距離が小さいほど類似)
SELECT
id,
title,
1 - (embedding <=> '[0.1, 0.2, ...]'::vector) AS similarity
FROM articles
ORDER BY embedding <=> '[0.1, 0.2, ...]'::vector
LIMIT 10;
コサイン類似度への変換:
-- コサイン距離 → コサイン類似度
-- 類似度 = 1 - 距離
SELECT
title,
1 - (embedding <=> query_embedding) AS similarity
FROM articles
WHERE 1 - (embedding <=> query_embedding) > 0.7 -- 類似度70%以上
ORDER BY similarity DESC;
インデックスの作成
大量のデータに対して高速な検索を行うには、インデックスの作成が必要です。
IVFFlat インデックス
近似最近傍探索(ANN)のためのインデックス。データをクラスタに分割し、検索対象を絞り込みます。
-- IVFFlatインデックスの作成
CREATE INDEX ON articles
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);
パラメータ:
lists: クラスタ数(推奨: 行数の平方根、または行数/1000)vector_cosine_ops: コサイン距離用の演算子クラス
| データ量 | 推奨lists値 |
|---|---|
| 〜10,000行 | 100 |
| 〜100,000行 | 300 |
| 〜1,000,000行 | 1000 |
HNSW インデックス
Hierarchical Navigable Small World。IVFFlatより高精度だが、インデックス構築が遅い。
-- HNSWインデックスの作成
CREATE INDEX ON articles
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
パラメータ:
m: グラフの接続数(デフォルト: 16)ef_construction: 構築時の探索範囲(デフォルト: 64)
インデックスの選択指針
| 観点 | IVFFlat | HNSW |
|---|---|---|
| 構築速度 | 速い | 遅い |
| 検索精度 | 良好 | 優秀 |
| メモリ使用量 | 少ない | 多い |
| 更新への対応 | 再構築が必要な場合あり | 動的更新可能 |
RPC関数の作成
検索ロジックをデータベース関数としてカプセル化すると便利です。
-- 類似記事検索関数
CREATE OR REPLACE FUNCTION search_articles(
query_embedding VECTOR(1536),
match_threshold FLOAT DEFAULT 0.7,
match_count INT DEFAULT 10
)
RETURNS TABLE (
id INT,
title TEXT,
content TEXT,
similarity FLOAT
)
LANGUAGE plpgsql
AS $$
BEGIN
RETURN QUERY
SELECT
articles.id,
articles.title,
articles.content,
1 - (articles.embedding <=> query_embedding) AS similarity
FROM articles
WHERE 1 - (articles.embedding <=> query_embedding) > match_threshold
ORDER BY articles.embedding <=> query_embedding
LIMIT match_count;
END;
$$;
使用例:
-- 関数を呼び出して検索
SELECT * FROM search_articles(
'[0.1, 0.2, ...]'::vector,
0.7, -- 類似度閾値
10 -- 最大件数
);
パフォーマンスのヒント
1. 適切なインデックスを選択
- 数万件以下: インデックスなしでも可
- 数十万件: IVFFlat
- 数百万件以上: HNSW
2. probes パラメータの調整(IVFFlat)
-- 検索時に探索するクラスタ数を増やす(精度向上、速度低下)
SET ivfflat.probes = 10;
3. ef_search パラメータの調整(HNSW)
-- 検索時の探索範囲を広げる(精度向上、速度低下)
SET hnsw.ef_search = 100;
4. 部分インデックス
特定の条件に絞ったインデックスを作成:
-- カテゴリが 'topics' の記事のみインデックス
CREATE INDEX ON articles
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100)
WHERE category = 'topics';
制限事項
- 次元数の上限: 2000次元まで(pgvector 0.5.0以降は16000次元)
- インデックスの再構築: IVFFlatは大量のデータ追加後に再構築が推奨
- メモリ使用量: HNSWは特にメモリを消費
関連トピック
- 検索技術の基礎 - ベクトル検索の基本概念
- Supabase + pgvector - Supabaseでpgvectorを使う方法
- Embedding APIの選択 - 埋め込み生成APIの選択肢
- Supabase - Supabaseの概要