pgvector: PostgreSQL を Vector データベースに変える
2026 年、コミュニティの理念が明確になりました。 「Postgresを使用するだけ」。 Snowflake が Crunchy Data を 2 億 5,000 万ドルで買収、Databricks が投資 Neonでは10億ドル、Supabaseの評価額は50億ドルに達しました。 PostgreSQLではありません さらに単なるリレーショナル データベース: ベクター、ベクトルデータベースになります 完全で、追加することなく埋め込み、類似性検索、AI 操作を管理できます。 スタックに対する単一のサービス。
すでに PostgreSQL を使用している場合 (統計的にも使用している)、Pinecone は必要ありません。 Qdrant または Weaviate でベクトル検索を開始します。この記事では、 ゼロから始める完全なベクター検索システム: pgvector のインストールから 埋め込みと統合の生成による、最適化されたインデックスの作成 ラングチェーンで。
シリーズ概要
| # | アイテム | 集中 |
|---|---|---|
| 1 | あなたはここにいます - pgvector | インストール、オペレーター、インデックス作成 |
| 2 | 埋め込みの詳細 | モデル、チャンキング、ディメンション |
| 3 | PostgreSQL を使用した RAG | エンドツーエンドの RAG パイプライン |
| 4 | ハイブリッド検索 | ベクター + 全文検索 |
| 5 | スケーリング pgvector | パーティショニング、シャーディング、パフォーマンス |
| 6 | 本番環境の pgvector | モニタリング、バックアップ、CI/CD |
何を学ぶか
- pgvector とは何ですか、またそれが 2026 年の最も重要な PostgreSQL 拡張機能である理由
- Linux、Docker、マネージドサービス (Supabase、Neon、AWS RDS) に pgvector をインストールする方法
- ベクトル列を含むテーブルを作成し、埋め込みを挿入する方法
- 3 つの距離演算子: コサイン、L2、内積
- 効果的な類似性検索クエリを実行する方法
- Python でエンベディングを生成する方法 (OpenAI と Sentence Transformers)
- HNSW と IVFFlat: どのインデックスを選択し、どのように構成するか
- pgvector と専用ベクター データベースのベンチマーク
- Python を使用した完全なエンドツーエンドの例
- RAG システムの LangChain との統合
1. 2026 年の「Postgres だけを使う」トレンド
何年もの間、AI の世界は、Pinecone、Weaviate、Qdrant、などの専用ベクトル データベースを目指してきました。 ミルバス。各 RAG プロジェクトには、管理、監視、支払いのために新しいサービスが必要であるようでした。 しかし、2025 年から 2026 年にかけて、何かが根本的に変わりました。
コミュニティは私がそれを理解しました ベクトルはデータベースの一種ではありません、しかし、 データ型。 PostgreSQL が JSON、配列、ジオメトリ、テキストを管理するのと同じように 全文検索を備え、高次元ベクトルも扱うことができます。という拡張子 これをすべて可能にするのが ベクター.
2026 年に「Postgres だけを使用する」理由
| 要素 | 専用のベクターデータベース | PostgreSQL + pgvector |
|---|---|---|
| インフラストラクチャー | 管理する新しいサービス | 既存DBへの拡張 |
| 料金 | 別プラン(松ぼっくり月額70ドル~) | PostgreSQLのコストに含まれる |
| データの一貫性 | DB間の同期が必要 | ネイティブ ACID トランザクション |
| クエリ | 独自のAPI | 標準 SQL + JOIN、WHERE、GROUP BY |
| バックアップ | セパレートシステム | pg_dump にはすべてが含まれます |
| チーム | 必要な特定のスキル | SQLに詳しい人なら誰でも |
主な利点は、 操作の簡単さ。 pgvector を使用すると、埋め込み これらはリレーショナル データと同じテーブルに存在します。ベクトルとメタデータを結合できます。 フィルタリングには WHERE 句を使用し、トランザクションの一貫性を確保します。からの外部サービスはありません 同期するため、別の API を学ぶ必要はありません。
2.pgvectorとは
ベクター サポートを追加する PostgreSQL のオープンソース拡張機能 高次元ベクトルと類似性検索にネイティブです。アンドリュー・ケインによって作成されました 2021 年に、すぐに AI/ML ユースケースで最もダウンロードされる PostgreSQL 拡張機能になりました。
pgvector を使用すると、次のことが可能になります。
- ベクトル (埋め込み) をテーブルの列にネイティブ データ型として保存します
- 3 つの異なる距離メトリックを使用して類似性検索を実行する
- 高速検索のための特殊なインデックス (HNSW および IVFFlat) を作成します。
- ベクトル検索と PostgreSQL が提供するすべての機能 (JOIN、トランザクション、トリガー、マテリアライズド ビュー) を組み合わせます。
Numbers の pgvector (2026)
| メトリック | 価値 |
|---|---|
| 現在のバージョン | 0.8.0+ (反復インデックススキャンあり) |
| 最大。キャリアのサイズ | 16,000 |
| インデックスの種類 | ハイニューサウスウェールズ州、IVFフラット |
| ベクトルの種類 | ベクター、ハーフベック、スパーセベック、ビット |
| 距離メトリクス | コサイン、L2 (ユークリッド)、内積 |
| 支援者 | AWS RDS、Supabase、Neon、Google Cloud SQL、Azure |
| ライセンス | PostgreSQL ライセンス (オープンソース) |
2025 年にリリースされたバージョン 0.8.0 では、主要な機能である gli が導入されました。 反復インデックススキャン。この機能はオーバーフィルターの問題を解決します。 つまり、ほとんどの場合、ベクトル インデックスが十分な結果を返さない場合です。 WHERE フィルターによって破棄されます。反復スキャンにより、pgvector はインデックスの探索を続けます。 フィルターに一致する十分な結果が見つかるまで、結果が大幅に改善されます。 フィルタリングされたクエリの品質。
3.pgvectorのインストール
pgvector は環境に応じてさまざまな方法でインストールされます。 3つのアプローチを見てみましょう 主なもの: Linux でのネイティブ インストール、Docker、マネージド サービス。
3.1 Ubuntu/Debian へのインストール
# Prerequisiti: PostgreSQL 14+ già installato
sudo apt-get update
sudo apt-get install -y postgresql-server-dev-16
# Clona e compila pgvector
git clone --branch v0.8.0 https://github.com/pgvector/pgvector.git
cd pgvector
make
sudo make install
# Abilita l'estensione nel tuo database
sudo -u postgres psql -d il_tuo_database -c "CREATE EXTENSION vector;"
PostgreSQL 17 の場合は、次のように置き換えます。 postgresql-server-dev-16 con
postgresql-server-dev-17。 pgvector はバージョン 13 以降 PostgreSQL をサポートしています
午後5時に。
3.2 Dockerを使用したインストール
始めるための最も早い方法。公式画像 pgvector/pgvector
pgvector がプリインストールされた PostgreSQL が含まれています。
# docker-compose.yml
version: '3.8'
services:
postgres:
image: pgvector/pgvector:pg17
environment:
POSTGRES_DB: vectordb
POSTGRES_USER: admin
POSTGRES_PASSWORD: secret_password
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
volumes:
pgdata:
-- init.sql: eseguito automaticamente al primo avvio
CREATE EXTENSION IF NOT EXISTS vector;
# Avvio rapido senza docker-compose
docker run -d \
--name pgvector-db \
-e POSTGRES_DB=vectordb \
-e POSTGRES_PASSWORD=secret \
-p 5432:5432 \
pgvector/pgvector:pg17
# Connetti e abilita pgvector
docker exec -it pgvector-db psql -U postgres -d vectordb \
-c "CREATE EXTENSION vector;"
3.3 マネージド サービス (ゼロセットアップ)
インフラストラクチャを管理したくない場合は、いくつかのクラウド サービスが PostgreSQL を提供しています。 pgvector はすでに有効になっています。これは生産にとって理想的な選択です。
pgvector を使用したマネージド サービス
| サービス | pgvector が含まれています | 無料プラン | 注意事項 |
|---|---|---|---|
| スーパーベース | プリインストール済み | はい (500MB) | ダッシュボード UI、自動 REST API |
| ネオン | プリインストール済み | はい (0.5GB) | サーバーレス、ブランチ データベース |
| AWS RDS | 有効にする | No | Aurora PostgreSQL 上の pgvector 0.8.0 |
| GoogleクラウドSQL | 有効にする | No | pgvector 0.8.0 のサポート |
| Azureデータベース | 有効にする | No | pgvector を使用したフレキシブル サーバー |
-- Su Supabase, pgvector e già disponibile.
-- Basta abilitare l'estensione:
CREATE EXTENSION IF NOT EXISTS vector;
-- Verifica l'installazione
SELECT extversion FROM pg_extension WHERE extname = 'vector';
-- Risultato: 0.8.0
4. ベクトルを使用したテーブルの作成
pgvector がインストールされていると、型列を追加できます vector(n) あなたへ
テーブル、ここで n そしてベクトルの次元数。の値 n
それは使用する埋め込みモデルによって異なります: OpenAI text-embedding-3-small 生成する
1536 次元ベクトル、一方 text-embedding-3-large 3072まで上がります。
-- Abilita l'estensione (se non già fatto)
CREATE EXTENSION IF NOT EXISTS vector;
-- Tabella documenti per un sistema RAG
CREATE TABLE documents (
id BIGSERIAL PRIMARY KEY,
title VARCHAR(500) NOT NULL,
content TEXT NOT NULL,
source VARCHAR(255),
category VARCHAR(100),
embedding vector(1536),
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Aggiungi un commento alla colonna per documentazione
COMMENT ON COLUMN documents.embedding IS
'Embedding generato con OpenAI text-embedding-3-small (1536 dim)';
埋め込みを含むドキュメントを挿入する
挿入は通常の INSERT と同じように機能し、ベクトルを値の文字列として渡します。 角括弧内のカンマで区切ります。
-- Inserimento singolo
INSERT INTO documents (title, content, source, embedding)
VALUES (
'Introduzione a PostgreSQL',
'PostgreSQL e un database relazionale open-source potente e affidabile...',
'docs/postgres-intro.md',
'[0.023, -0.045, 0.067, 0.089, -0.012, ...]' -- vettore a 1536 dimensioni
);
-- Inserimento multiplo (batch)
INSERT INTO documents (title, content, source, category, embedding)
VALUES
('Capitolo 1', 'Contenuto cap 1...', 'libro.pdf', 'tutorial',
'[0.11, -0.22, 0.33, ...]'),
('Capitolo 2', 'Contenuto cap 2...', 'libro.pdf', 'tutorial',
'[0.44, -0.55, 0.66, ...]'),
('FAQ', 'Domande frequenti...', 'faq.md', 'supporto',
'[-0.12, 0.34, -0.56, ...]');
ベクトルサイズ
列定義で指定された次元 (vector(1536))
挿入する埋め込みのサイズと正確に一致する必要があります。試み
768 次元ベクトルを列に挿入するには vector(1536) 引き起こします
エラーです。使用する予定の埋め込みテンプレートに基づいてサイズを選択します。
一般的な埋め込みモデルの寸法
| モデル | プロバイダー | 寸法 | コスト/100万トークン |
|---|---|---|---|
| テキスト埋め込み-3-small | OpenAI | 1536年 | $0.02 |
| テキスト埋め込み-3-大 | OpenAI | 3072 | $0.13 |
| all-MiniLM-L6-v2 | ハグフェイス(無料) | 384 | 無料(ローカル) |
| all-mpnet-base-v2 | ハグフェイス(無料) | 768 | 無料(ローカル) |
| 航海-3 | 航海AI | 1024 | $0.06 |
5. 距離演算子
pgvector には、ベクトル間の距離を計算する 3 つの演算子が用意されています。すべてのオペレーター 別の数学的指標に対応しており、特定の使用例があります。
三人のオペレーター pgvector
| オペレーター | メトリック | Formula | 仕分け | 使用事例 |
|---|---|---|---|---|
<=> |
コサイン距離 | 1 - コサイン類似度 | ASC (0 = 同一) | テキスト、正規化された埋め込み |
<-> |
L2 (ユークリッド) | sqrt(sum((a-b)^2)) | ASC (0 = 同一) | 画像、空間データ |
<#> |
内積 (拒否) | -1 * ドット積 | ASC (負の値が大きい = 類似性が高い) | 正規化されたベクトル、最大のパフォーマンス |
-- COSINE DISTANCE <=> (il più usato per testo)
-- Risultato: 0 = identici, 2 = opposti
SELECT title, content,
embedding <=> '[0.1, 0.2, ...]' AS cosine_distance
FROM documents
ORDER BY embedding <=> '[0.1, 0.2, ...]' ASC
LIMIT 5;
-- L2 (EUCLIDEA) <->
-- Risultato: 0 = identici, valori crescenti = più lontani
SELECT title, content,
embedding <-> '[0.1, 0.2, ...]' AS l2_distance
FROM documents
ORDER BY embedding <-> '[0.1, 0.2, ...]' ASC
LIMIT 5;
-- INNER PRODUCT (NEGATO) <#>
-- Risultato: valori più negativi = più simili
SELECT title, content,
(embedding <#> '[0.1, 0.2, ...]') * -1 AS similarity
FROM documents
ORDER BY embedding <#> '[0.1, 0.2, ...]' ASC
LIMIT 5;
どのオペレーターを選択するか
テキストと AI を使用するユースケースの 90% では、次を使用します。 <=> (コサイン距離)。
OpenAI のような埋め込みモデルは正規化されたベクトルを生成します。
コサイン距離と内積は結果の点で等価です。アメリカ合衆国 <->
(L2) ベクトルの大きさが重要となる空間データまたは画像を操作する場合のみ。
内積 (<#>) を回避するため、コサインよりわずかに高速です。
正規化しますが、すでに正規化されたベクトルのみを対象とします。
6. 類似性検索クエリ
類似検索は pgvector の核心です。基本的なクエリは単純です。結果を並べ替えます。 クエリ ベクトルからの距離によって、最初の K を取得します。しかし、運用環境では、クエリは次のようになります。 ベクトル検索と SQL フィルターを組み合わせることで、より高度な検索が可能になります。
6.1 基本的なクエリ
-- Trova i 5 documenti più simili a un vettore query
SELECT
id,
title,
content,
1 - (embedding <=> $1) AS similarity -- $1 = vettore query
FROM documents
ORDER BY embedding <=> $1
LIMIT 5;
6.2 フィルターを使用したクエリ (pgvector の真の能力)
ここでは、専用のベクター データベースと比較して pgvector が優れています。検索を組み合わせることができます 任意の SQL 句を含むベクトル: WHERE、JOIN、GROUP BY、サブクエリ。
-- Filtra per categoria e soglia di similarità
SELECT
id, title, content,
1 - (embedding <=> $1) AS similarity
FROM documents
WHERE category = 'tutorial'
AND created_at > NOW() - INTERVAL '30 days'
ORDER BY embedding <=> $1
LIMIT 5;
-- JOIN con altre tabelle: trova documenti simili con info autore
SELECT
d.title,
d.content,
a.name AS author_name,
1 - (d.embedding <=> $1) AS similarity
FROM documents d
JOIN authors a ON d.author_id = a.id
WHERE a.verified = true
ORDER BY d.embedding <=> $1
LIMIT 10;
-- Esclusione: trova simili ma NON il documento stesso
SELECT
id, title,
1 - (embedding <=> (SELECT embedding FROM documents WHERE id = 42)) AS similarity
FROM documents
WHERE id != 42
ORDER BY embedding <=> (SELECT embedding FROM documents WHERE id = 42)
LIMIT 5;
6.3 反復インデックススキャン (pgvector 0.8.0)
バージョン 0.8.0 の最も重要な新機能の 1 つは、 反復インデックススキャン。ベクトル検索と WHERE フィルターを組み合わせる場合 制限が厳しいため、インデックスは最初のパスで十分なヒットを見つけられない可能性があります。 反復スキャンでは、pgvector は満足するまでインデックスをスキャンし続けます。 要求された LIMIT。
-- Abilita iterative scan per HNSW
SET hnsw.iterative_scan = relaxed_order; -- o strict_order
-- Imposta il limite massimo di tuple da scansionare
SET hnsw.max_scan_tuples = 20000;
-- Ora le query con filtri restrittivi funzionano correttamente
SELECT id, title,
1 - (embedding <=> $1) AS similarity
FROM documents
WHERE category = 'raro' -- categoria con pochi documenti
ORDER BY embedding <=> $1
LIMIT 10;
-- Senza iterative scan: potrebbe restituire 0-3 risultati
-- Con iterative scan: restituisce sempre fino a 10 risultati
-- Modalità disponibili:
-- off = comportamento tradizionale (default)
-- strict_order = mantiene l'ordine esatto delle distanze
-- relaxed_order = ordine approssimato (migliori performance)
反復スキャンを使用する場合
- リラックスした注文: ほとんどの場合、パフォーマンスと品質の最適なバランスが得られます。
- strict_order: 距離の正確な順序が重要な場合 (例: ユーザーに対する結果のランキング)
- オフ: WHERE フィルターがない場合、またはフィルターに制限がない場合
7. Python で埋め込みを生成する
pgvector にデータを入力するには、まず次のコマンドを使用してテキストを数値ベクトルに変換する必要があります。 埋め込みモデル。 2 つのアプローチを見てみましょう: OpenAI API (有料、高品質) および Sentence Transformers (無料、ローカル)。
7.1 OpenAI API を使用する
import openai
import psycopg2
from psycopg2.extras import execute_values
# Configura il client OpenAI
client = openai.OpenAI(api_key="sk-...")
def get_embedding(text: str, model: str = "text-embedding-3-small") -> list[float]:
"""Genera un embedding per un testo usando OpenAI."""
response = client.embeddings.create(
input=text,
model=model
)
return response.data[0].embedding # lista di 1536 float
# Connetti a PostgreSQL
conn = psycopg2.connect(
host="localhost",
database="vectordb",
user="admin",
password="secret_password"
)
cur = conn.cursor()
# Genera e inserisci embeddings
documents = [
("Introduzione a Python", "Python e un linguaggio di programmazione versatile..."),
("PostgreSQL Avanzato", "Le CTE ricorsive permettono di eseguire query gerarchiche..."),
("Docker per Sviluppatori", "I container Docker isolano le applicazioni..."),
]
for title, content in documents:
embedding = get_embedding(content)
cur.execute(
"INSERT INTO documents (title, content, embedding) VALUES (%s, %s, %s)",
(title, content, str(embedding))
)
conn.commit()
cur.close()
conn.close()
7.2 文トランスフォーマーを使用する場合 (無料およびローカル)
from sentence_transformers import SentenceTransformer
import psycopg2
import numpy as np
# Carica il modello (scaricato automaticamente la prima volta)
model = SentenceTransformer('all-MiniLM-L6-v2') # 384 dimensioni
# Genera embeddings per un batch di testi
texts = [
"Python e un linguaggio di programmazione versatile",
"Le CTE ricorsive permettono query gerarchiche in SQL",
"I container Docker isolano le applicazioni",
]
embeddings = model.encode(texts) # shape: (3, 384)
# Connetti e inserisci
conn = psycopg2.connect(
host="localhost", database="vectordb",
user="admin", password="secret_password"
)
cur = conn.cursor()
# NOTA: la colonna deve essere vector(384), non vector(1536)
for text, embedding in zip(texts, embeddings):
cur.execute(
"INSERT INTO documents (title, content, embedding) VALUES (%s, %s, %s)",
(text[:100], text, str(embedding.tolist()))
)
conn.commit()
cur.close()
conn.close()
OpenAI vs 文トランスフォーマー
| 待ってます | OpenAI API | センテンストランスフォーマー |
|---|---|---|
| 料金 | $0.02 / 100万トークン | 無料 |
| 品質 | 優れた (最先端) | 良い (多くの場合に十分) |
| プライバシー | OpenAIに送信されるデータ | すべてローカルで、データの流出はありません |
| スピード | リクエストごとに最大 100 ミリ秒 (ネットワーク) | テキストの場合は約 10 ミリ秒 (GPU 使用時) |
| オフライン | いいえ (インターネットが必要です) | はい (最初のダウンロード後) |
| 寸法 | 1536 または 3072 | 384 または 768 (モデルによって異なります) |
埋め込みの黄金律
使ってください 同じ埋め込みモデル ドキュメントのインデックス作成と
クエリベクトルを生成します。さまざまなモデルで生成されたエンベディングが存在します
ベクトル空間が異なるため比較できません。インデックスを付けた場合
text-embedding-3-small、同じモデルで検索する必要があります。
8. インデックス作成: HNSW と IVFFlat
インデックスがない場合、pgvector は逐次 (総当たり) スキャンを実行して比較します。 テーブルの各行を含むクエリ ベクトル。これは 100% 正確ですが、次のようになります。 データセットが大きい場合は遅くなります。近似最近傍 (ANN) インデックスの犠牲 桁違いに高速な検索を実現するための精度の最小パーセンテージ。
8.1 ニューサウスウェールズ州インデックス
HNSW (Hierarchical Navigable Small World) は接続のマルチレベル グラフを構築します キャリア間。そして、ほとんどの場合に推奨されるインデックスは、高速読み取り、 精度が高く、再構築を行わずに増分挿入をサポートします。
-- Indice HNSW con parametri di default
CREATE INDEX idx_documents_embedding_hnsw
ON documents
USING hnsw (embedding vector_cosine_ops);
-- Indice HNSW con parametri personalizzati
CREATE INDEX idx_documents_embedding_hnsw
ON documents
USING hnsw (embedding vector_cosine_ops)
WITH (
m = 24, -- connessioni per nodo (default: 16, range: 2-100)
ef_construction = 128 -- candidati durante costruzione (default: 64, range: 4-1000)
);
-- Regola ef_search per le query (default: 40)
SET hnsw.ef_search = 100; -- più alto = più preciso ma più lento
HNSW パラメータ: 構成ガイド
| パラメータ | デフォルト | 範囲 | 効果 | アドバイスする |
|---|---|---|---|---|
m |
16 | 2~100 | より多くの接続 = より正確でより多くのメモリ | ほとんどの場合は 16 ~ 32 |
ef_construction |
64 | 4~1000 | 高い = インデックスが良くなり、ビルドが遅くなります | 64-256 (1 回限り、上げる価値あり) |
ef_search |
40 | 1~1000 | 高い = より正確、検索は遅くなります | 望ましいトレードオフに基づいて 40 ~ 200 |
8.2 IVFFlat インデックス
IVFFlat (フラット圧縮による反転ファイル) はベクトルをクラスターに分割し、検索のみを行います。 クエリに最も近いクラスター内。 HNSW よりもビルドが速くなりますが、次のものが必要です。 大量の新しいデータを追加した場合の再構築。データセットの変更に最適 まれに。
-- IMPORTANTE: IVFFlat richiede dati nella tabella PRIMA di creare l'indice
-- (necessità di fare clustering k-means sui dati esistenti)
-- Indice IVFFlat
CREATE INDEX idx_documents_embedding_ivf
ON documents
USING ivfflat (embedding vector_cosine_ops)
WITH (
lists = 100 -- numero di cluster (default: 100)
);
-- Regola il numero di cluster da esplorare durante la ricerca
SET ivfflat.probes = 10; -- default: 1, consigliato: sqrt(lists)
-- Regola pratica per "lists":
-- rows < 1M: lists = rows / 1000
-- rows >= 1M: lists = sqrt(rows)
8.3 距離タイプ別の演算子
インデックスの作成で指定された演算子は、演算子と一致する必要があります。 クエリで使用されます。こちらが完全な地図です。
マップ演算子とインデックスクラス
| 距離 | SQL演算子 | インデックスクラス (おっと) |
|---|---|---|
| ささいなこと | <=> |
vector_cosine_ops |
| L2 (ユークリッド) | <-> |
vector_l2_ops |
| 内積 | <#> |
vector_ip_ops |
8.4 HNSW と IVFFlat: どちらを選択するか
HNSW と IVFFlat の比較
| 待ってます | ニューサウスウェールズ州 | IVFフラット |
|---|---|---|
| 検索速度 | もっと早く | 速い |
| 精度(再現率) | ~95-99% | ~90-98% |
| ビルド時間 | 遅い | 速い |
| メモリ | 高い | 平均 |
| 増分挿入 | サポートされています | REINDEX が必要です |
| 反復スキャン | はい (0.8.0) | はい (0.8.0) |
| 理想的な使用例 | 一般的な使用、増加するデータ | 静的データセット、高速ビルド |
実践的なアドバイス
ほとんどのプロジェクトでは、 ニューサウスウェールズ州を選択。さらに多用途に対応し、 リビルドなしの増分挿入、および pgvector のバージョン 0.8.0 には パフォーマンスが大幅に向上しました。 IVFFlat は、次の場合にのみ使用してください。 インデックス構築とクリティカル (非常に大きなデータセットは 1 回だけロードされる) o メモリ制限が厳しい場合。
9. パフォーマンス: pgvector と専用ベクター データベース
最もよくある質問は、「pgvector は運用に十分な速さですか?」です。答えは 2026年には si、ほとんどのユースケースに対応します。 数字を見てみましょう。
9.1 大規模なベンチマーク
pgvectorscale ベンチマーク (Timescale によって開発された pgvector の補完的な拡張機能) 5,000 万の通信事業者のうち、素晴らしい結果を示しています。
ベンチマーク: 99% の再現率で 5,000 万のベクトル
| システム | QPS (クエリ/秒) | 想起 | 注意事項 |
|---|---|---|---|
| pgベクトルスケール | 471 | 99% | Qdrant より 11.4 倍高速 |
| クドラント | 41 | 99% | 純粋なベクトル検索用に最適化 |
9.2 中規模ベンチマーク (100 万ベクトル)
ベンチマーク: 1M ベクトル - スループット
| システム | クエリ/秒 | インサート/秒 | 管理コスト |
|---|---|---|---|
| 松ぼっくり | ~5,000 | ~50,000 | 月額70ドルから |
| クドラント | ~4,500 | ~45,000 | セルフホストまたはクラウド |
| ベクター | ~3,000 | ~30,000 | PGコストに含まれます |
1M ベクターでは、pgvector の純粋なスループットがわずかに遅くなります。しかし、考慮すると コストは実質的にゼロである (そして既に PostgreSQL に含まれている) というレポートです。 品質と価格、そして無敵。ほとんどの Web アプリケーションの場合、3,000 クエリ 毎秒それらは十分すぎるほどです。
pgvector が不十分な場合
次の場合は、専用のベクトル データベース (Qdrant、Pinecone) を検討してください。
- もう終わりです 5000万 ベクトルの
- p99 レイテンシーが i 以下である必要があります。 5ミリ秒
- ワークロードはベクトル検索のみです (リレーショナル データはありません)
- ネイティブ分散シャーディングが必要です
それ以外の場合は、pgvector が正しい選択です。 1,000 万ベクトル以下のシステム PostgreSQL がすでにスタック内にあるため、追加の複雑さは必要ありません。
10. 完全な例: Python を使用したナレッジベース
すべてを実際の例にまとめてみましょう。次のような知識ベースを構築します。 埋め込みを使用してドキュメントにインデックスを付け、類似性検索を可能にし、フィルターをサポートします カテゴリごとに。
"""
Knowledge Base con PostgreSQL + pgvector
Requisiti: pip install openai psycopg2-binary
"""
import openai
import psycopg2
from dataclasses import dataclass
# === Configurazione ===
OPENAI_API_KEY = "sk-..."
DB_CONFIG = {
"host": "localhost",
"database": "vectordb",
"user": "admin",
"password": "secret_password",
}
EMBEDDING_MODEL = "text-embedding-3-small"
EMBEDDING_DIM = 1536
@dataclass(frozen=True)
class SearchResult:
id: int
title: str
content: str
similarity: float
category: str
# === Funzioni di embedding ===
client = openai.OpenAI(api_key=OPENAI_API_KEY)
def get_embedding(text: str) -> list[float]:
"""Genera un embedding per un testo."""
response = client.embeddings.create(
input=text,
model=EMBEDDING_MODEL,
)
return response.data[0].embedding
def get_embeddings_batch(texts: list[str]) -> list[list[float]]:
"""Genera embeddings per un batch di testi (più efficiente)."""
response = client.embeddings.create(
input=texts,
model=EMBEDDING_MODEL,
)
return [item.embedding for item in response.data]
# === Setup del database ===
def setup_database() -> None:
"""Crea la tabella e gli indici."""
conn = psycopg2.connect(**DB_CONFIG)
cur = conn.cursor()
cur.execute("CREATE EXTENSION IF NOT EXISTS vector;")
cur.execute(f"""
CREATE TABLE IF NOT EXISTS kb_documents (
id BIGSERIAL PRIMARY KEY,
title VARCHAR(500) NOT NULL,
content TEXT NOT NULL,
category VARCHAR(100) DEFAULT 'general',
embedding vector({EMBEDDING_DIM}),
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
""")
cur.execute("""
CREATE INDEX IF NOT EXISTS idx_kb_embedding_hnsw
ON kb_documents
USING hnsw (embedding vector_cosine_ops)
WITH (m = 24, ef_construction = 128);
""")
cur.execute("""
CREATE INDEX IF NOT EXISTS idx_kb_category
ON kb_documents (category);
""")
conn.commit()
cur.close()
conn.close()
print("Database setup completato.")
# === Inserimento documenti ===
def insert_documents(
documents: list[dict],
batch_size: int = 50,
) -> None:
"""Inserisce documenti con embeddings generati automaticamente."""
conn = psycopg2.connect(**DB_CONFIG)
cur = conn.cursor()
for i in range(0, len(documents), batch_size):
batch = documents[i : i + batch_size]
texts = [doc["content"] for doc in batch]
embeddings = get_embeddings_batch(texts)
for doc, emb in zip(batch, embeddings):
cur.execute(
"""INSERT INTO kb_documents (title, content, category, embedding)
VALUES (%s, %s, %s, %s)""",
(doc["title"], doc["content"],
doc.get("category", "general"), str(emb)),
)
print(f"Inseriti {min(i + batch_size, len(documents))}/{len(documents)} documenti")
conn.commit()
cur.close()
conn.close()
# === Ricerca per similarità ===
def search(
query: str,
limit: int = 5,
category: str | None = None,
min_similarity: float = 0.3,
) -> list[SearchResult]:
"""Cerca documenti simili alla query."""
query_embedding = get_embedding(query)
conn = psycopg2.connect(**DB_CONFIG)
cur = conn.cursor()
# Abilita iterative scan per filtri restrittivi
cur.execute("SET hnsw.iterative_scan = relaxed_order;")
if category:
cur.execute(
"""SELECT id, title, content, category,
1 - (embedding <=> %s::vector) AS similarity
FROM kb_documents
WHERE category = %s
ORDER BY embedding <=> %s::vector
LIMIT %s""",
(str(query_embedding), category,
str(query_embedding), limit),
)
else:
cur.execute(
"""SELECT id, title, content, category,
1 - (embedding <=> %s::vector) AS similarity
FROM kb_documents
ORDER BY embedding <=> %s::vector
LIMIT %s""",
(str(query_embedding), str(query_embedding), limit),
)
results = [
SearchResult(
id=row[0], title=row[1], content=row[2],
category=row[3], similarity=row[4],
)
for row in cur.fetchall()
if row[4] >= min_similarity
]
cur.close()
conn.close()
return results
# === Main ===
if __name__ == "__main__":
# 1. Setup
setup_database()
# 2. Inserisci documenti di esempio
sample_docs = [
{
"title": "Introduzione a PostgreSQL",
"content": "PostgreSQL e un RDBMS open-source con supporto ACID completo.",
"category": "database",
},
{
"title": "Indici in PostgreSQL",
"content": "I B-tree sono il tipo di indice default. HNSW e usato per vettori.",
"category": "database",
},
{
"title": "Cos'è il RAG",
"content": "RAG combina retrieval e generation per risposte basate su documenti.",
"category": "ai",
},
{
"title": "Docker per Sviluppatori",
"content": "Docker isola le applicazioni in container leggeri e portabili.",
"category": "devops",
},
{
"title": "Embeddings e Vector Search",
"content": "Gli embeddings trasformano testo in vettori per la similarity search.",
"category": "ai",
},
]
insert_documents(sample_docs)
# 3. Cerca documenti
print("\n--- Ricerca: 'come funzionano i database vettoriali' ---")
results = search("come funzionano i database vettoriali", limit=3)
for r in results:
print(f" [{r.similarity:.3f}] {r.title} ({r.category})")
print("\n--- Ricerca filtrata per categoria 'ai' ---")
results = search("tutorial su PostgreSQL", limit=3, category="ai")
for r in results:
print(f" [{r.similarity:.3f}] {r.title} ({r.category})")
11. LangChainとの統合
RAG システムを構築している場合、LangChain は pgvector との直接統合を提供します
パッケージを通して langchain-postgres。これにより、使用できるようになります
SQL を手動で記述することなく、PostgreSQL をベクター ストアとして使用できます。
pip install langchain-postgres langchain-openai psycopg
from langchain_postgres import PGVector
from langchain_openai import OpenAIEmbeddings
from langchain_core.documents import Document
# Configura il modello di embedding
embeddings = OpenAIEmbeddings(
model="text-embedding-3-small",
openai_api_key="sk-...",
)
# NOTA: langchain-postgres usa psycopg3 (non psycopg2)
CONNECTION_STRING = "postgresql+psycopg://admin:secret@localhost:5432/vectordb"
# Crea il vector store
vector_store = PGVector(
embeddings=embeddings,
collection_name="langchain_docs",
connection=CONNECTION_STRING,
use_jsonb=True, # metadati JSONB per filtri efficienti
)
# Aggiungi documenti
docs = [
Document(
page_content="pgvector trasforma PostgreSQL in un vector database",
metadata={"source": "tutorial.md", "chapter": 1},
),
Document(
page_content="HNSW e l'indice consigliato per la maggior parte dei casi",
metadata={"source": "tutorial.md", "chapter": 2},
),
Document(
page_content="LangChain semplifica la costruzione di sistemi RAG",
metadata={"source": "guida-rag.md", "chapter": 1},
),
]
vector_store.add_documents(docs)
# Ricerca per similarità
results = vector_store.similarity_search(
"come creare un indice vettoriale",
k=3,
)
for doc in results:
print(f"[{doc.metadata['source']}] {doc.page_content[:80]}...")
# Ricerca con score
results_with_scores = vector_store.similarity_search_with_score(
"cos'è pgvector",
k=3,
)
for doc, score in results_with_scores:
print(f"[Score: {score:.4f}] {doc.page_content[:80]}...")
# Usa come retriever in una catena RAG
retriever = vector_store.as_retriever(
search_type="similarity",
search_kwargs={"k": 5},
)
# Il retriever può essere usato direttamente nelle chain LangChain
relevant_docs = retriever.invoke("installazione pgvector docker")
psycopg3 に関する注意事項
パッケージ langchain-postgres 必要 サイコpg3 (サイコpg2ではありません)。
接続文字列には次の形式を使用する必要があります。 postgresql+psycopg:// の代わりに postgresql+psycopg2://。から移行する場合 langchain-community、
接続文字列を更新します。
12. 運用環境における pgvector のベスト プラクティス
12.1 ベクトルサイズ
ベクトルが小さいほど、占有するスペースが少なくなり、インデックスが高速になり、コストが削減されます。
OpenAI text-embedding-3-small (1536 ディム) が最高の価値を提供します
ほとんどの場合、品質サイズ。多少の損失を許容できるなら
品質の、 all-MiniLM-L6-v2 (384 ディム) と素晴らしい自由な選択が可能です。
12.2 バッチ挿入
from psycopg2.extras import execute_values
# SBAGLIATO: un INSERT alla volta (lento)
for doc in documents:
cur.execute("INSERT INTO docs (content, embedding) VALUES (%s, %s)",
(doc.content, str(doc.embedding)))
# CORRETTO: batch insert con execute_values (10-50x più veloce)
data = [
(doc.content, str(doc.embedding))
for doc in documents
]
execute_values(
cur,
"INSERT INTO docs (content, embedding) VALUES %s",
data,
page_size=500, # righe per batch SQL
)
conn.commit()
12.3 接続プーリング
運用環境では、リクエストごとに新しい PostgreSQL 接続を開かないでください。
次のような接続プールを使用します Pgバウンサー または統合プーリング
psycopg2.
from psycopg2 import pool
# Crea un pool di connessioni (all'avvio dell'applicazione)
connection_pool = pool.ThreadedConnectionPool(
minconn=5, # connessioni minime
maxconn=20, # connessioni massime
host="localhost",
database="vectordb",
user="admin",
password="secret_password",
)
# Usa una connessione dal pool
conn = connection_pool.getconn()
try:
cur = conn.cursor()
cur.execute("SELECT ... ORDER BY embedding <=> %s LIMIT 5", ...)
results = cur.fetchall()
cur.close()
finally:
connection_pool.putconn(conn) # restituisci al pool
12.4 メンテナンス
-- VACUUM per recuperare spazio dopo DELETE/UPDATE
VACUUM ANALYZE documents;
-- Ricostruisci l'indice IVFFlat dopo inserimenti massicci
REINDEX INDEX CONCURRENTLY idx_documents_embedding_ivf;
-- NOTA: HNSW non richiede REINDEX per nuovi inserimenti
-- Monitora la dimensione dell'indice
SELECT
indexname,
pg_size_pretty(pg_relation_size(indexname::regclass)) AS size
FROM pg_indexes
WHERE tablename = 'documents';
-- Verifica che l'indice venga usato
EXPLAIN ANALYZE
SELECT id, 1 - (embedding <=> '[0.1, 0.2, ...]') AS similarity
FROM documents
ORDER BY embedding <=> '[0.1, 0.2, ...]'
LIMIT 5;
-- Cerca "Index Scan using idx_..._hnsw" nell'output
生産チェックリスト
- HNSW インデックスを作成するには
m = 24eef_construction = 128 - Imposta
ef_searchレイテンシーと精度のトレードオフに基づいて 40 ~ 200 の間 - 能力
hnsw.iterative_scan = relaxed_orderWHERE フィルターを使用する場合 - バッチ挿入を使用する
execute_values大量の負荷に対応 - 接続プール (PgBouncer または psycopg2.pool) をセットアップします。
- スケジュール
VACUUM ANALYZE定期的な - クエリを監視する
EXPLAIN ANALYZEインデックスの使用を確認するには - アメリカ合衆国
halfvecの代わりにvectorスペースを 50% 節約します (float16 精度で十分な場合)
結論
pgvector は、PostgreSQL を単純なリレーショナル データベースから AI 対応プラットフォームに変換しました。 バージョン 0.8.0 とその反復インデックス スキャンにより、ベクトル データベースとのギャップが解消されました。 専用のプロジェクトは大幅に減少し、ほとんどのプロジェクトでは 1,000 万未満 多くの通信事業者がいる場合、スタックに別のサービスを追加する理由はありません。
この記事では、pgvector をインストールし、ベクター列を含むテーブルを作成する方法を学びました。 3 つの距離演算子を使用して類似性検索を実行し、Python でエンベディングを生成し、 HNSW インデックスと IVFFlat インデックスを設定し、すべてを LangChain と統合します。あなたも見たことがありますか? 本番環境での pgvector のパフォーマンスを確認するベンチマーク。
Nel 次の記事 それらをさらに深く掘り下げていきます 埋め込み: 内部でどのように機能するか、適切なモデルを選択する方法、チャンキング戦略 長いドキュメントの場合と、検索品質を最適化する方法について説明します。で 3番目の記事 私たちはそれを構築します RAG パイプラインが完了しました PostgreSQL を唯一のバックエンドとして使用します。
追加リソース
- pgvector GitHub: github.com/pgvector/pgvector - 公式ドキュメントと変更ログ
- pgvectorscale: github.com/timescale/pgvectorscale - パフォーマンス拡張機能の強化
- ラングチェーン PGVector: python.langchain.com - 公式の Python 統合
- スーパーベースベクトル: supabase.com/docs/guides/ai - Supabase の pgvector ガイド
- ネオンAI: neon.tech/docs/ai - Neon サーバーレスの pgvector







