「PostgreSQL でベクトル検索(意味検索)をやりたい」——その入口が pgvector です。専用のベクトルDBを増やさず、いま使っている Postgres に vector 型を1つ足すだけで、AIの埋め込みベクトルを保存して「意味が近い順」に検索できるようになります。
この記事は、その最初の一歩——各プラットフォームでの有効化と最初のベクトル検索——を最短で踏み出すための入門ガイドです。「RAGの全体設計」や「インデックスのチューニング」は別記事に譲り、本稿は**「動かす」ところまで**を、公式ドキュメントに忠実に、つまずきポイントを潰しながら案内します。
この記事のルール:拡張名・SQL構文・各プラットフォームの有効化手順は pgvector 公式 README と各クラウドの公式ドキュメント(2026年6月時点) に基づきます。マネージドサービスの pgvector バージョンはエンジンのマイナーに紐づき、本家より遅れます。利用前に必ずお使いのインスタンスで
pg_available_extensionsを確認してください。本記事のバージョン・手順は変わり得ます。
1. 30秒で理解する pgvector
pgvector は PostgreSQL の拡張(extension) です。有効化すると次の3つが使えるようになります。
vector型:埋め込みベクトル([0.1, -0.3, ...]のような数値配列)を格納する列の型。- 距離演算子:
<=>(コサイン距離)など、ベクトル間の「近さ」を測る演算子。 - ANNインデックス:HNSW / IVFFlat。数百万行でも高速に近傍を返す近似最近傍インデックス。
最重要の注意点を先に。拡張の名前は vector です(pgvector ではありません)。 pgvector はプロジェクト名。SQLで有効化するときは、どのプラットフォームでも必ずこう書きます。
CREATE EXTENSION vector; -- ✅ 正しい(拡張名は vector)
-- CREATE EXTENSION pgvector; -- ❌ これは存在しないのでエラーになる
2. プラットフォーム別:pgvector を有効化する
「CREATE EXTENSION vector; を実行する」のは共通ですが、**その前提(バイナリのインストール/許可リスト/権限)**がプラットフォームで違います。あなたの環境の節だけ読めば十分です。
Docker / セルフホスト
最短は公式 Docker イメージです。イメージ名は pgvector/pgvector、タグは「Postgresメジャー + Debianベース」の形(例 pg17)。
# 公式イメージ(pgvector がプリインストール済みの Postgres)
docker pull pgvector/pgvector:pg17
docker run -d --name pg -e POSTGRES_PASSWORD="$PGPASSWORD" -p 5432:5432 pgvector/pgvector:pg17
既存の Postgres にソースから入れる場合(pg_config が PATH に必要):
cd /tmp
git clone --branch v0.8.3 https://github.com/pgvector/pgvector.git
cd pgvector && make && sudo make install
OSパッケージでも入ります(NN は Postgres メジャー)。
sudo apt install postgresql-17-pgvector # Debian/Ubuntu(PGDG apt)
sudo dnf install pgvector_17 # RHEL/Fedora(PGDG yum)
brew install pgvector # macOS
最後に、対象のデータベースで一度だけ実行します。
CREATE EXTENSION vector;
Supabase
ダッシュボードの Database → Extensions で「vector」を検索してトグルをONにするか、SQLエディタで実行します。Supabase の慣習では extensions スキーマに入れます。
create extension vector with schema extensions;
AWS RDS for PostgreSQL / Aurora PostgreSQL
pgvector は RDS / Aurora の trusted extension(信頼済み拡張) として提供されます。バイナリは導入済みなので、有効化するだけです。
-- まず使えるバージョンを確認(マネージドは本家より遅れることがある)
SELECT * FROM pg_available_extensions WHERE name = 'vector';
CREATE EXTENSION IF NOT EXISTS vector;
- 権限:PostgreSQL 13以降なら、データベースへの
CREATE権限があればrds_superuserでなくても trusted extension を入れられます(12以前はrds_superuserが必要)。 - HNSWインデックスを使うには pgvector 0.5.0 以降が必要。古いマイナーだと未対応のことがあるので、上の
pg_available_extensionsで確認してください。
Neon
全プランで利用可。追加設定も特別な権限も不要です。
CREATE EXTENSION IF NOT EXISTS vector;
-- 一つ前のバージョンに固定したいとき
-- CREATE EXTENSION vector VERSION '0.7.4';
Google Cloud SQL for PostgreSQL / AlloyDB
Cloud SQL はフラグ不要で有効化できます。作成できるのは cloudsqlsuperuser ロールのメンバー(デフォルトの postgres ユーザーは保持)。
CREATE EXTENSION vector; -- 名前は vector(pgvector ではない)
AlloyDB は pgvector に加えて Google 独自の ScaNN インデックスも使えます。CASCADE で vector も同時に入ります。
CREATE EXTENSION IF NOT EXISTS alloydb_scann CASCADE; -- alloydb_scann + vector
Azure Database for PostgreSQL — Flexible Server
Azure だけは2段階です。先に許可リスト(azure.extensions)へ登録してから CREATE EXTENSION します。許可リストでも名前は vector。
# 1) サーバーパラメータ azure.extensions に VECTOR を許可(CLIの例)
az postgres flexible-server parameter set \
--resource-group <rg> --server-name <server> \
--name azure.extensions --value vector
-- 2) 対象DBで有効化(権限: azure_pg_admin)
CREATE EXTENSION vector;
早見表:有効化コマンドと必要権限
| プラットフォーム | 事前準備 | 有効化 | 必要権限 |
|---|---|---|---|
| Docker / セルフホスト | イメージ or make install | CREATE EXTENSION vector; | superuser |
| Supabase | (導入済み) | create extension vector with schema extensions; | (UI/SQLで可) |
| RDS / Aurora | (導入済み・trusted) | CREATE EXTENSION vector; | CREATE on DB(PG13+)/rds_superuser(PG≤12) |
| Neon | 不要 | CREATE EXTENSION vector; | 特別な権限不要 |
| Cloud SQL / AlloyDB | (導入済み) | CREATE EXTENSION vector; | cloudsqlsuperuser |
| Azure Flexible Server | azure.extensions に登録 | CREATE EXTENSION vector; | azure_pg_admin |
3. 確認とよくあるエラー
有効化できたかは、どの環境でも同じSQLで確認できます。
SELECT extversion FROM pg_extension WHERE extname = 'vector'; -- 入っていればバージョンが返る
SELECT * FROM pg_available_extensions WHERE name = 'vector'; -- 入れられるバージョン
psql なら \dx で一覧、\dx vector で詳細。つまずきの大半は次の2つです。意味を知っていれば即座に切り分けられます。
| エラー | 本当の意味 | 対処 |
|---|---|---|
could not open extension control file ".../vector.control": No such file or directory | バイナリが未インストール(権限の問題ではない) | make install / 正しいPGメジャーのパッケージ / pgvector入りDockerイメージを使う |
permission denied to create extension "vector" | ロールの権限不足 | superuser / rds_superuser / cloudsqlsuperuser / azure_pg_admin、または DBへの CREATE 権限を付与 |
extension "vector" is not allow-listed for "azure.extensions" setting | Azure で許可リスト未登録 | azure.extensions に vector を追加してから再実行 |
4. 最初のベクトル検索
有効化できたら、いよいよ検索です。テーブル作成 → 投入 → kNN検索の最小フローを通します。
-- 1) 埋め込みを格納するテーブル。vector(3) の 3 は次元数(実際は埋め込みモデルの出力次元に合わせる)
CREATE TABLE items (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
content text NOT NULL,
embedding vector(3) NOT NULL
);
-- 2) 投入。ベクトルは '[...]' のテキストリテラルで渡す
INSERT INTO items (content, embedding) VALUES
('りんご', '[1, 2, 3]'),
('みかん', '[1, 2, 4]'),
('自動車', '[9, 8, 1]');
-- 3) クエリベクトルに「意味が近い順」で上位2件(kNN検索)
SELECT id, content, embedding <=> '[1, 2, 3]' AS distance
FROM items
ORDER BY embedding <=> '[1, 2, 3]' -- 小さいほど近い
LIMIT 2;
距離演算子:用途に合わせて選ぶ
ベクトルの「近さ」をどう測るかは演算子で選びます。埋め込みモデルが想定する距離に合わせるのが鉄則です。
| 演算子 | 距離 | 主な用途 |
|---|---|---|
<=> | コサイン距離 | テキスト埋め込みの定番(向きで意味を測る) |
<-> | L2(ユークリッド)距離 | 正規化していないベクトル全般 |
<#> | 負の内積 | 内積ベースのモデル |
<+> | L1(マンハッタン)距離 | L1空間 |
<~> / <%> | ハミング / ジャッカード距離 | bit 型(バイナリベクトル) |
OpenAI の text-embedding-3-* のようなテキスト埋め込みなら、まず <=>(コサイン距離) を選んでおけば間違いありません。
実データではどうなる?:上の
'[1,2,3]'は説明用の手書きベクトルです。実際は埋め込みモデル(OpenAI・Cohere・自前モデルなど)にテキストを渡して得た数百〜数千次元のベクトルをINSERTします。アプリ側からの渡し方は、TypeScript × Drizzle の型安全な実装で詳しく扱います。
5. 4つのベクトル型と次元の上限
pgvector には用途別に4つの型があります。まず vector で始め、必要になったら他を検討すれば十分です(YAGNI)。
| 型 | 1要素のサイズ | インデックス可能な次元 | 使いどころ |
|---|---|---|---|
vector(n) | 4バイト(float32) | 最大 2,000 | 標準。まずこれ |
halfvec(n) | 2バイト(float16) | 最大 4,000 | メモリ半減・高次元 |
bit(n) | 1ビット | 最大 64,000 | バイナリ量子化(ハミング距離) |
sparsevec(n) | 非ゼロのみ格納 | 非ゼロ最大 16,000 | スパース表現(SPLADE等) |
vector(n) の n は埋め込みモデルの出力次元と一致させる必要があります(ズレると INSERT で次元不一致エラー=型で守られる利点)。OpenAI の text-embedding-3-large は3072次元ですが、dimensions パラメータで短縮でき、私のプロジェクトでは1024次元で運用しています(理由はRAG設計の記事で詳述)。
6. 最初のインデックス(HNSW)
数件なら全件スキャンで十分ですが、数百万行になると毎回のフルスキャンが破綻します。そこで近似最近傍(ANN)インデックスを張ります。迷ったら HNSW(継続的な追加に強く、空テーブルにも先に張れる)。
-- コサイン距離で検索するなら vector_cosine_ops(距離演算子と演算子クラスを必ず揃える)
CREATE INDEX ON items USING hnsw (embedding vector_cosine_ops);
-- 検索精度↔速度は、インデックス再構築なしでランタイムに調整できる
SET hnsw.ef_search = 100; -- 既定40。大きいほど高再現率・低速
インデックスが効いているかは EXPLAIN で確認します(Index Scan using ..._hnsw_... が出ればOK)。
EXPLAIN ANALYZE
SELECT id FROM items ORDER BY embedding <=> '[1,2,3]' LIMIT 5;
重要:インデックスは「
ORDER BY embedding <演算子> ... LIMIT k」という形にだけ効きます。m/ef_construction/ef_searchといったパラメータの意味や、HNSW と IVFFlat の選び方、再現率の測り方は、専用記事 pgvector チューニング完全ガイド に体系化しています。
7. 次に読むべき記事(ここから本番へ)
「動いた」次は、目的に応じてこの順で深掘りすると最短です。
- RAG(社内文書にAIが答える)を作りたい → pgvector で作る本番RAG(埋め込みの置き場所・ハイブリッド検索・冪等インジェスト)
- 検索が遅い/精度が出ない → pgvector チューニング完全ガイド(HNSW/IVFFlat・量子化・再現率の計測)
- 専用ベクトルDBと迷っている → pgvector vs Pinecone/Qdrant/Weaviate/Milvus 技術選定
- TypeScript / Next.js で型安全に実装したい → pgvector × Drizzle ORM × Next.js
まとめ:最短チェックリスト
- 拡張名は
vector。有効化はどの環境でもCREATE EXTENSION vector;の一行。 - プラットフォーム差は「前提」だけ:Docker は公式イメージ
pgvector/pgvector:pg17、Azure だけazure.extensions許可が先。マネージドのバージョンはpg_available_extensionsで確認。 - エラーは2系統:
control file が無い=バイナリ未導入、permission denied=権限不足。 - 最初の検索:
vector(n)列 →INSERT '[...]'→ORDER BY embedding <=> $1 LIMIT k。テキストは<=>。 - 規模が出たら HNSW:
USING hnsw (embedding vector_cosine_ops)、精度はhnsw.ef_searchで調整。
pgvector の良さは、いま使っている PostgreSQL の中で、使い慣れた SQL・権限・バックアップのままベクトル検索を始められることです。私は 生成AI音声チャットボット で、専用ベクトルDBを増設せず RDS 上の pgvector に業務データと埋め込みを集約し、本番RAGを一人 × 生成AI(Claude Code)で設計・実装・運用まで通しました。
「自社のデータでAIの意味検索を始めたいが、どこに・どう載せるか分からない」——その入口から本番運用までを一気通貫で伴走できます。 お気軽にご相談ください。
参考(公式ドキュメント)
- pgvector(GitHub・README) — インストール(Docker / ソース / OSパッケージ)・
CREATE EXTENSION vector・型と距離演算子・HNSW / IVFFlat - Supabase — pgvector / AWS RDS 拡張 / Neon — pgvector / Google Cloud SQL 拡張 / Azure Flexible Server で pgvector を使う