Skip to content

✍️ 필사 모드: Vector Database 完全ガイド 2025:エンベディング、類似度検索、Pinecone/Weaviate/Qdrant/pgvector

日本語
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

1. なぜVector Databaseなのか

1.1 従来(じゅうらい)の検索の限界

従来のデータベースは正確なキーワードマッチングに基づいています。「子犬(こいぬ)が公園(こうえん)で遊(あそ)んでいる」で検索すると、「犬(いぬ)が芝生(しばふ)で走(はし)っている」は見つかりません。2つの文は意味的にほぼ同じですが、キーワードが異なるためです。

従来の検索: "子犬 公園" → キーワードマッチ → "子犬""公園"を含む文書のみ返却
ベクトル検索: "子犬 公園" → 意味ベクトル化 → 類似した意味の全文書を返却
"犬が芝生で走っている" ✅ 発見
"ペットの散歩スポット推薦" ✅ 発見

1.2 Vector Databaseが解決する問題

Vector Databaseはデータを高次元(こうじげん)ベクトル(数値配列)として保存し、ベクトル間の類似度(るいじど)に基づいて検索します。

主要ユースケース:

領域説明
RAG(検索拡張生成)LLMに関連文書コンテキストを提供ChatGPT + 社内文書
セマンティック検索意味ベースの検索自然言語質問検索
レコメンドシステム類似アイテムの発見商品/コンテンツ推薦
画像検索視覚的類似性「この服に似た商品」
異常検知正常パターンから逸脱したデータ不正取引検知
重複検出類似コンテンツの識別盗作検知、重複文書

1.3 市場成長

Vector Database市場は2024年の15億ドルから2028年に約60億ドルへの成長が見込まれています。RAGパイプラインの爆発的な採用が主要な推進力です。


2. ベクトルエンベディングの基礎(きそ)

2.1 エンベディングとは

エンベディングとは、テキスト、画像(がぞう)、音声(おんせい)などの非構造化データを高次元空間の数値ベクトルに変換(へんかん)することです。意味的に類似したデータはベクトル空間で近くに位置します。

from openai import OpenAI

client = OpenAI()

# テキストをベクトルに変換
response = client.embeddings.create(
    model="text-embedding-3-large",
    input="Vector DatabaseはAI時代の重要なインフラです"
)

embedding = response.data[0].embedding
print(f"次元数: {len(embedding)}")     # 3072
print(f"ベクトルサンプル: {embedding[:5]}")  # [0.023, -0.041, 0.017, ...]

2.2 テキストエンベディングモデル比較

モデルプロバイダー次元MTEBスコア費用特徴
text-embedding-3-largeOpenAI307264.6有料次元削減サポート
text-embedding-3-smallOpenAI153662.3低コストコスパ優秀
embed-v3.0Cohere102464.5有料多言語優秀
BGE-M3BAAI102468.2無料OSS最強
Jina-embeddings-v3Jina AI102465.5無料多言語特化
all-MiniLM-L6-v2SBERT38456.3無料軽量高速
nomic-embed-textNomic76862.4無料ロングコンテキスト

2.3 画像エンベディング

CLIP(Contrastive Language-Image Pre-Training)モデルは、テキストと画像を同じベクトル空間にマッピングします。

from sentence_transformers import SentenceTransformer
from PIL import Image

model = SentenceTransformer("clip-ViT-B-32")

# 画像エンベディング
img = Image.open("cat_photo.jpg")
img_embedding = model.encode(img)

# テキストエンベディング(同じベクトル空間)
text_embedding = model.encode("a cute orange cat")

# テキストで画像検索が可能!
from numpy import dot
from numpy.linalg import norm

similarity = dot(img_embedding, text_embedding) / (
    norm(img_embedding) * norm(text_embedding)
)
print(f"類似度: {similarity:.4f}")  # 0.28+ (関連があれば高い)

2.4 マルチモーダルエンベディング

最新モデルはテキスト、画像、音声を1つのベクトル空間に統合します。

テキスト: "海の上の夕焼け" ──┐
                             ├──→ 同一ベクトル空間 → 類似度比較可能
画像: (夕焼けの写真)       ──┘

3. 距離(きょり)メトリクス(類似度測定)

3.1 コサイン類似度(Cosine Similarity)

2つのベクトル間の角度(かくど)を測定します。ベクトルの大きさ(長さ)は無視し、方向のみを比較します。

import numpy as np

def cosine_similarity(a, b):
    return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

# 例: 3次元ベクトル
vec_a = np.array([1, 2, 3])
vec_b = np.array([2, 4, 6])  # 同じ方向、大きさのみ異なる
vec_c = np.array([-1, -2, -3])  # 反対方向

print(cosine_similarity(vec_a, vec_b))  # 1.0 (完全に同じ方向)
print(cosine_similarity(vec_a, vec_c))  # -1.0 (完全に反対方向)

使用場面: テキストエンベディング(最も一般的)、正規化されたベクトル

3.2 ユークリッド距離(Euclidean Distance / L2)

2つのベクトル間の直線距離を測定します。値が小さいほど類似しています。

def euclidean_distance(a, b):
    return np.linalg.norm(a - b)

vec_a = np.array([1, 2])
vec_b = np.array([4, 6])

print(euclidean_distance(vec_a, vec_b))  # 5.0

使用場面: ベクトルの大きさが意味を持つ場合、クラスタリング

3.3 内積(ないせき)(Dot Product / Inner Product)

2つのベクトルの内積です。方向と大きさの両方を考慮します。

def dot_product(a, b):
    return np.dot(a, b)

vec_a = np.array([1, 2, 3])
vec_b = np.array([4, 5, 6])

print(dot_product(vec_a, vec_b))  # 32

使用場面: Maximum Inner Product Search(MIPS)、正規化されたベクトルではコサイン類似度と同等

3.4 マンハッタン距離(Manhattan Distance / L1)

各次元の絶対差の合計です。

def manhattan_distance(a, b):
    return np.sum(np.abs(a - b))

vec_a = np.array([1, 2, 3])
vec_b = np.array([4, 6, 3])

print(manhattan_distance(vec_a, vec_b))  # 7 (3 + 4 + 0)

3.5 メトリクス選択ガイド

テキストエンベディング検索   → コサイン類似度(デフォルト推奨)
画像類似度検索             → ユークリッド距離
レコメンドシステム(MIPS)  → 内積
高次元スパースベクトル      → コサイン類似度
クラスタリング / 分類       → ユークリッド距離

4. インデキシングアルゴリズム

ベクトルが数百万個ある場合、全ベクトルと1つずつ比較(Brute-force)すると遅すぎます。インデキシングアルゴリズムは検索速度を数千倍高速化します。

4.1 HNSW(Hierarchical Navigable Small World)

最も広く使われているANN(Approximate Nearest Neighbor)アルゴリズムです。

動作原理(どうさげんり):

Layer 3: [A] ────────────────── [B]     (少数ノード、長距離リンク)
           \                   /
Layer 2: [A] ── [C] ── [D] ── [B]      (中間ノード)
           \   / \   / \   / \
Layer 1: [A]-[E]-[C]-[F]-[D]-[G]-[B]   (大部分のノード、短距離リンク)
           |   |   |   |   |   |   |
Layer 0: [全ベクトルが存在する基本層]      (全ノード)
  • 上位レイヤーで大まかな位置を特定し、下位レイヤーで精密検索
  • グラフベースのためメモリ使用量が多いが、非常に高速
# QdrantでのHNSW設定例
from qdrant_client import QdrantClient
from qdrant_client.models import VectorParams, HnswConfigDiff

client = QdrantClient("localhost", port=6333)

client.create_collection(
    collection_name="documents",
    vectors_config=VectorParams(
        size=1536,
        distance="Cosine"
    ),
    hnsw_config=HnswConfigDiff(
        m=16,                    # ノード当たり接続数(高いほど正確、メモリ増加)
        ef_construct=128,        # インデックス構築時の探索範囲
        full_scan_threshold=10000  # この数以下はbrute-force
    )
)

主要パラメータ:

パラメータ説明デフォルト効果
Mノード当たり接続数16高くすると精度/メモリ増加
ef_construct構築探索範囲128高くするとインデックス品質向上
ef_search検索探索範囲64高くすると検索精度向上、速度低下

4.2 IVF(Inverted File Index)

ベクトルをクラスタに分割し、検索時に最も近いクラスタのみを探索します。

ベクトル空間:
┌─────────────────────────────────┐
* *   X **  Cluster1  *  **  *          X* *  Cluster2  **     *  * **   ** *  *         XCluster3        Cluster4*  * *         *  *  *└─────────────────────────────────┘
X = クラスタ中心(centroid)

検索: クエリに最も近いクラスタ(nprobe個)内のみ検索

4.3 IVF-PQ(IVF + Product Quantization)

PQはベクトルを圧縮してメモリ使用量を削減します。

# FAISSでIVF-PQインデックス作成
import faiss

dimension = 1536
nlist = 256      # クラスタ数
m_pq = 48        # サブベクトル数(次元をm_pq個に分割)
nbits = 8        # 各サブベクトルのコードブックサイズ

quantizer = faiss.IndexFlatL2(dimension)
index = faiss.IndexIVFPQ(quantizer, dimension, nlist, m_pq, nbits)

# 学習データでクラスタ + コードブック学習
index.train(training_vectors)
index.add(all_vectors)

# 検索時のnprobe設定
index.nprobe = 16  # 探索するクラスタ数
distances, indices = index.search(query_vector, k=10)

メモリ比較:

元データ(float32, 1536次元): 1536 x 4 bytes = 6,144 bytes/ベクトル
PQ圧縮(48サブベクトル):    48 x 1 byte  = 48 bytes/ベクトル
128倍圧縮!1億ベクトル: 614GB → 4.8GB

4.4 ScaNN(Scalable Nearest Neighbors)

Googleが開発(かいはつ)したアルゴリズムです。非対称ハッシュと量子化を組み合わせ、高いrecallでも高速な検索を提供します。

4.5 Annoy(Approximate Nearest Neighbors Oh Yeah)

Spotifyが開発したアルゴリズムです。空間をランダムなハイパープレーンで再帰的に分割し、ツリーを構築します。読み取り専用インデックスでメモリマップ方式をサポートし、複数プロセスで共有可能です。

4.6 アルゴリズム比較

アルゴリズム検索速度メモリインデックス構築精度適合規模
Flat(Brute-force)遅い高いなし100%10万以下
HNSW非常に速い高い遅い非常に高い数百万
IVF-Flat速い中間普通高い数千万
IVF-PQ速い低い普通中間数億
ScaNN非常に速い中間普通高い数億
Annoy速い低い速い中間数千万

5. Vector Database比較

5.1 主要ソリューション比較表

特性PineconeWeaviateQdrantMilvusChromapgvector
タイプマネージドSaaSOSS/クラウドOSS/クラウドOSSOSSPostgreSQL拡張
インデックス独自アルゴリズムHNSWHNSWHNSW/IVF/DiskANNHNSWHNSW/IVF
ハイブリッド検索Sparse-DenseBM25 + VectorSparse + Denseサポート制限的Full-text + Vector
フィルタリングメタデータフィルタGraphQLフィルタPayloadフィルタ属性フィルタWhere句SQL WHERE
マルチテナンシーネームスペーステナント分離コレクション/Payloadパーティションコレクションスキーマ/RLS
最大次元20,00065,53565,53532,768制限なし2,000
分散処理自動Raft合意Raft合意分散アーキテクチャ非サポートCitus拡張
SDKPython/JS/Go/JavaPython/JS/Go/JavaPython/JS/Rust/GoPython/JS/Go/JavaPython/JSSQL
価格Pod/ServerlessプランOSS無料OSS無料OSS無料OSS無料無料

5.2 Pinecone

完全マネージドVector Databaseです。インフラ管理なしでAPIのみで使用します。

from pinecone import Pinecone, ServerlessSpec

pc = Pinecone(api_key="YOUR_KEY")

# インデックス作成
pc.create_index(
    name="my-index",
    dimension=1536,
    metric="cosine",
    spec=ServerlessSpec(
        cloud="aws",
        region="us-east-1"
    )
)

index = pc.Index("my-index")

# ベクトルアップサート
index.upsert(
    vectors=[
        ("id1", [0.1, 0.2, ...], {"title": "文書タイトル", "category": "tech"}),
        ("id2", [0.3, 0.4, ...], {"title": "別の文書", "category": "science"}),
    ],
    namespace="articles"
)

# 検索(フィルタ + ベクトル)
results = index.query(
    vector=[0.15, 0.25, ...],
    top_k=5,
    filter={"category": "tech"},
    namespace="articles",
    include_metadata=True
)

利点: 完全マネージド、即座スケーリング、Serverlessオプション 欠点: ベンダーロックイン、コスト高い、セルフホスティング不可

5.3 Weaviate

GraphQLベースのAPIと内蔵ベクトル化モジュールを提供するオープンソースVector Databaseです。

import weaviate
from weaviate.classes.config import Configure, Property, DataType

client = weaviate.connect_to_local()

# コレクション作成(内蔵ベクトル化)
collection = client.collections.create(
    name="Article",
    vectorizer_config=Configure.Vectorizer.text2vec_openai(
        model="text-embedding-3-small"
    ),
    properties=[
        Property(name="title", data_type=DataType.TEXT),
        Property(name="content", data_type=DataType.TEXT),
        Property(name="category", data_type=DataType.TEXT),
    ]
)

# データ追加(自動ベクトル化)
articles = client.collections.get("Article")
articles.data.insert(
    properties={
        "title": "Vector DBガイド",
        "content": "ベクトルデータベースはAI時代の核心...",
        "category": "tech"
    }
)

# セマンティック検索
response = articles.query.near_text(
    query="人工知能インフラ",
    limit=5,
    filters=weaviate.classes.query.Filter.by_property("category").equal("tech")
)

利点: 内蔵ベクトル化、GraphQL API、モジュールエコシステム 欠点: リソース消費が多い、学習曲線

5.4 Qdrant

Rustで書かれた高性能Vector Databaseです。ペイロードフィルタリングと量子化に強みがあります。

from qdrant_client import QdrantClient
from qdrant_client.models import (
    Distance, VectorParams, PointStruct,
    Filter, FieldCondition, MatchValue
)

client = QdrantClient("localhost", port=6333)

# コレクション作成
client.create_collection(
    collection_name="articles",
    vectors_config=VectorParams(
        size=1536,
        distance=Distance.COSINE
    )
)

# ベクトルアップサート
client.upsert(
    collection_name="articles",
    points=[
        PointStruct(
            id=1,
            vector=[0.1, 0.2, ...],
            payload={"title": "Vector DBガイド", "category": "tech", "views": 1500}
        ),
    ]
)

# フィルタ + ベクトル検索
results = client.search(
    collection_name="articles",
    query_vector=[0.15, 0.25, ...],
    query_filter=Filter(
        must=[
            FieldCondition(key="category", match=MatchValue(value="tech")),
        ]
    ),
    limit=5
)

利点: Rustベースの性能、きめ細かいフィルタリング、Scalar/Binary量子化 欠点: エコシステムが比較的小さい

5.5 ChromaDB

軽量で開発者(かいはつしゃ)フレンドリーなオープンソースVector Databaseです。プロトタイピングに最適です。

import chromadb

client = chromadb.PersistentClient(path="./chroma_db")

collection = client.create_collection(
    name="articles",
    metadata={"hnsw:space": "cosine"}
)

# ドキュメント追加(自動エンベディング)
collection.add(
    documents=["Vector DBはAIインフラの核心です", "RAGは検索拡張生成です"],
    metadatas=[{"category": "tech"}, {"category": "ai"}],
    ids=["doc1", "doc2"]
)

# 検索
results = collection.query(
    query_texts=["人工知能データベース"],
    n_results=5,
    where={"category": "tech"}
)

利点: 超簡単API、内蔵エンベディング、ローカル実行 欠点: プロダクションスケーリングの制限、分散非サポート


6. pgvector ディープダイブ

6.1 なぜpgvectorなのか

すでにPostgreSQLを使用しているなら、別のVector Databaseなしで既存インフラにベクトル検索を追加できます。SQLの豊富な機能とベクトル検索を組み合わせます。

6.2 インストールとセットアップ

-- PostgreSQL 14+が必要
-- 拡張インストール
CREATE EXTENSION IF NOT EXISTS vector;

-- ベクトルカラムを持つテーブル作成
CREATE TABLE documents (
    id BIGSERIAL PRIMARY KEY,
    title TEXT NOT NULL,
    content TEXT,
    category TEXT,
    embedding VECTOR(1536),  -- OpenAI text-embedding-3-small次元
    created_at TIMESTAMPTZ DEFAULT NOW()
);

6.3 データ挿入と検索

-- ベクトル挿入
INSERT INTO documents (title, content, category, embedding)
VALUES (
    'Vector DBガイド',
    'Vector DatabaseはAI時代の核心...',
    'tech',
    '[0.1, 0.2, 0.3, ...]'::vector  -- 1536次元ベクトル
);

-- コサイン距離検索(最も類似した5件)
SELECT id, title, 1 - (embedding <=> '[0.15, 0.25, ...]'::vector) AS similarity
FROM documents
WHERE category = 'tech'
ORDER BY embedding <=> '[0.15, 0.25, ...]'::vector
LIMIT 5;

-- L2距離検索
SELECT id, title, embedding <-> '[0.15, 0.25, ...]'::vector AS distance
FROM documents
ORDER BY embedding <-> '[0.15, 0.25, ...]'::vector
LIMIT 5;

6.4 HNSW vs IVFFlatインデックス

-- HNSWインデックス(推奨)
CREATE INDEX ON documents
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 128);

-- 検索時のef_search設定
SET hnsw.ef_search = 100;

-- IVFFlatインデックス
CREATE INDEX ON documents
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);  -- クラスタ数(sqrt(rows)推奨)

-- 検索時のprobes設定
SET ivfflat.probes = 10;

HNSW vs IVFFlat比較:

特性HNSWIVFFlat
検索速度より速い速い
インデックス構築遅い速い
メモリより多いより少ない
精度(Recall)より高い中間
リアルタイム挿入優秀再構築が必要な場合あり
推奨デフォルト選択メモリ制約がある場合

6.5 クエリ最適化

-- 1. 部分インデックス(特定カテゴリのみ)
CREATE INDEX ON documents
USING hnsw (embedding vector_cosine_ops)
WHERE category = 'tech';

-- 2. フィルタ + ベクトル検索のパーティション活用
-- 遅いパターン: ベクトル検索後にフィルタ
SELECT * FROM documents
WHERE category = 'tech'
ORDER BY embedding <=> query_vec
LIMIT 10;

-- 速いパターン: パーティションテーブル活用
CREATE TABLE documents_tech PARTITION OF documents
FOR VALUES IN ('tech');

-- 3. EXPLAINでインデックス使用確認
EXPLAIN (ANALYZE, BUFFERS)
SELECT id, title
FROM documents
ORDER BY embedding <=> '[0.15, 0.25, ...]'::vector
LIMIT 5;

7. ハイブリッド検索

7.1 なぜハイブリッド検索なのか

ベクトル検索だけでは不十分な場合があります。

クエリ: "PostgreSQL 16 リリースノート"

ベクトル検索のみ: "MySQL 8.0 新機能"も高い類似度(似た意味)
キーワード検索のみ: "PostgreSQL 16"が正確に含まれる文書のみ
ハイブリッド検索: 意味的に類似 + "PostgreSQL 16"を含む = 最適な結果

7.2 BM25 + Vector結合

# Weaviateのハイブリッド検索
response = articles.query.hybrid(
    query="PostgreSQL vector search performance",
    alpha=0.5,  # 0 = キーワードのみ, 1 = ベクトルのみ, 0.5 = バランス
    limit=10,
    fusion_type="relative_score"
)

7.3 Reciprocal Rank Fusion(RRF)

2つの検索結果のランキングを統合するアルゴリズムです。

def reciprocal_rank_fusion(keyword_results, vector_results, k=60):
    """
    RRFスコア = sum(1 / (k + rank_i))
    k = 60が一般的
    """
    scores = {}
    
    for rank, doc_id in enumerate(keyword_results):
        scores[doc_id] = scores.get(doc_id, 0) + 1 / (k + rank + 1)
    
    for rank, doc_id in enumerate(vector_results):
        scores[doc_id] = scores.get(doc_id, 0) + 1 / (k + rank + 1)
    
    return sorted(scores.items(), key=lambda x: x[1], reverse=True)

# 例
keyword_hits = ["doc_A", "doc_B", "doc_C", "doc_D"]
vector_hits = ["doc_C", "doc_A", "doc_E", "doc_B"]

fused = reciprocal_rank_fusion(keyword_hits, vector_hits)
# doc_Aとdoc_Cが両方で上位 → 最終上位

8. メタデータフィルタリング

8.1 フィルタリング戦略

ベクトル検索とメタデータフィルタを組み合わせる3つの戦略があります。

Pre-filtering:  フィルタ適用 → フィルタされたベクトルのみ検索(正確だが遅い場合あり)
Post-filtering: ベクトル検索 → 結果にフィルタ適用(速いが結果が少ない場合あり)
In-filtering:   検索中にフィルタを同時適用(最適だが実装が複雑)

8.2 Qdrant高度フィルタリング

from qdrant_client.models import Filter, FieldCondition, MatchValue, Range

results = client.search(
    collection_name="products",
    query_vector=query_embedding,
    query_filter=Filter(
        must=[
            FieldCondition(key="category", match=MatchValue(value="electronics")),
            FieldCondition(key="price", range=Range(gte=100, lte=500)),
        ],
        must_not=[
            FieldCondition(key="out_of_stock", match=MatchValue(value=True)),
        ],
        should=[
            FieldCondition(key="brand", match=MatchValue(value="Apple")),
            FieldCondition(key="brand", match=MatchValue(value="Samsung")),
        ]
    ),
    limit=10
)

9. プロダクション運用

9.1 シャーディング戦略

水平シャーディング: データを複数ノードに分散
┌─ Node 1 ─┐ ┌─ Node 2 ─┐ ┌─ Node 3 ─┐
Shard 1   │ │ Shard 2   │ │ Shard 333%データ │ │ 33%データ │ │ 33%データ │
└───────────┘ └───────────┘ └───────────┘
        ↕ 検索時にすべてのノードにクエリ後マージ

9.2 レプリケーション

# Qdrantレプリケーション設定
client.create_collection(
    collection_name="articles",
    vectors_config=VectorParams(size=1536, distance=Distance.COSINE),
    replication_factor=3,        # 3ノードにレプリケート
    write_consistency_factor=2   # 2ノード確認後書き込み成功
)

9.3 バックアップとリストア

# Qdrantスナップショット作成
curl -X POST "http://localhost:6333/collections/articles/snapshots"

# スナップショットリカバリ
curl -X PUT "http://localhost:6333/collections/articles/snapshots/recover" \
  -H "Content-Type: application/json" \
  -d '{"location": "http://backup-server/snapshot.tar"}'

# pgvector: pg_dump活用
pg_dump -t documents mydb > documents_backup.sql

9.4 モニタリング

monitoring_metrics = {
    "検索レイテンシ (p50, p95, p99)": "目標: p99 100ms以下",
    "QPS(秒当たりクエリ数)": "負荷に応じてモニタリング",
    "Recall@K": "精度。0.95以上を目標",
    "インデックスサイズ/メモリ使用量": "OOM防止",
    "挿入レイテンシ": "リアルタイム更新時に重要",
    "ディスク使用量": "容量計画",
    "レプリケーション遅延": "データ一貫性",
}

10. 性能ベンチマーク

10.1 ANNベンチマーク結果(100万ベクトル、128次元)

DB / アルゴリズムQPS(Recall 0.95)QPS(Recall 0.99)インデックス時間メモリ
Qdrant HNSW8,5004,20012分2.1GB
Weaviate HNSW7,8003,90014分2.3GB
Milvus HNSW9,2004,50011分2.0GB
pgvector HNSW3,4001,60025分2.5GB
Pinecone (p2)5,0002,800N/AN/A
FAISS IVF-PQ12,0005,5008分0.4GB

10.2 実戦ベンチマーク(1000万ベクトル、1536次元)

テスト環境: AWS r6g.2xlarge (8vCPU, 64GB RAM)

Qdrant:
  - インデックス構築: 45  - メモリ: 48GB
  - p50レイテンシ: 3ms, p99レイテンシ: 12ms
  - QPS: 2,100 (Recall@10 = 0.96)

pgvector (HNSW):
  - インデックス構築: 2時間30  - メモリ: 52GB
  - p50レイテンシ: 8ms, p99レイテンシ: 35ms
  - QPS: 800 (Recall@10 = 0.95)

Milvus (DiskANN):
  - インデックス構築: 35  - メモリ: 12GB(ディスクベース)
  - p50レイテンシ: 5ms, p99レイテンシ: 18ms
  - QPS: 1,800 (Recall@10 = 0.95)

10.3 ベンチマーク要約

小規模(10万以下)+ 既存PostgreSQL → pgvector
小規模プロトタイピング → ChromaDB
中規模(10万〜1000万)+ セルフホスティング → QdrantまたはWeaviate
大規模(1000++ セルフホスティング → Milvus
マネージドサービス希望 → PineconeまたはZilliz Cloud
ハイブリッド検索重要 → Weaviate
フィルタリング重要 → Qdrant

11. コスト分析

11.1 マネージドサービスコスト比較

サービス無料ティア有料開始価格100万ベクトル推定コスト
Pinecone Serverless2GBストレージ読み書き課金月約70ドル
Pinecone Pod (s1)-月70ドル月約140ドル
Weaviate Cloud14日無料月25ドル月約100ドル
Qdrant Cloud1GB無料月25ドル月約65ドル
Zilliz Cloud無料ティア従量制月約90ドル

11.2 セルフホスティングコスト

100万ベクトル(1536次元、HNSW)推定インフラ:
  - RAM必要: 約12GB
  - ディスク: 約20GB
  - AWS r6g.xlarge (4vCPU, 32GB): 月約150ドル
  - 運用人件費別途

1000万ベクトル:
  - RAM必要: 約100GB
  - AWS r6g.4xlarge (16vCPU, 128GB): 月約600ドル

コスト削減のヒント:
  - 量子化でメモリ6075%削減
  - DiskANNでSSD活用(メモリ80%削減)
  - 次元削減(1536512)でメモリ3倍節約

12. クイズ

Q1. コサイン類似度とユークリッド距離の違いは?

コサイン類似度は2つのベクトルの方向(角度) のみを比較します。ベクトルの大きさに関係なく、方向が同じなら1です。ユークリッド距離は2つのベクトル間の直線距離を測定し、ベクトルの大きさも結果に影響します。正規化されたベクトルでは、両メトリクスは同じ順序になります。テキストエンベディングにはコサイン類似度がデフォルト推奨です。

Q2. HNSWアルゴリズムのMパラメータを高くするとどうなりますか?

Mは各ノードの最大接続数です。Mを高くするとグラフがより密になり、検索精度(recall)が向上しますが、メモリ使用量が増加し、インデックス構築時間も長くなります。一般的にM=16がデフォルトで、高いrecallが必要ならM=32〜64に上げられます。非常に高い値は収穫逓減が発生します。

Q3. ハイブリッド検索でのRRF(Reciprocal Rank Fusion)の役割は?

RRFはキーワード検索とベクトル検索の結果をランキングベースで統合するアルゴリズムです。各文書のRRFスコアは1/(k + rank)で計算され、両方の検索結果で高いランクを持つ文書が最終的に上位に来ます。k=60が標準で、スコア正規化が不要という利点があります。

Q4. pgvectorのHNSWインデックスとIVFFlatインデックスのどちらを選ぶべきですか?

HNSWをデフォルト選択として推奨します。HNSWはより高いrecall、より速い検索速度、リアルタイム挿入サポートという利点があります。IVFFlatはメモリ制約が厳しい場合に検討します。IVFFlatはインデックス構築が速くメモリ使用量が少ないですが、データが頻繁に変更される場合は再構築(REINDEX)が必要になる可能性があります。

Q5. 1000万ベクトル規模でのコスト効率的なVector DB選択は?

セルフホスティングが可能なら: QdrantまたはMilvusがコスト効率的です。MilvusのDiskANNインデックスを使用するとメモリを大幅に節約できます。マネージドを希望なら: Pinecone Serverlessが従量制でコスト管理が可能です。量子化(Scalar/Binary)を適用するとメモリを60〜75%削減し、インフラコストを大幅に削減できます。次元削減(1536から512へ)も効果的です。


13. 参考資料(さんこうしりょう)

  1. Pinecone Documentation - https://docs.pinecone.io/
  2. Weaviate Documentation - https://weaviate.io/developers/weaviate
  3. Qdrant Documentation - https://qdrant.tech/documentation/
  4. Milvus Documentation - https://milvus.io/docs
  5. pgvector GitHub - https://github.com/pgvector/pgvector
  6. ChromaDB Documentation - https://docs.trychroma.com/
  7. ANN Benchmarks - https://ann-benchmarks.com/
  8. FAISS Wiki - https://github.com/facebookresearch/faiss/wiki
  9. OpenAI Embeddings Guide - https://platform.openai.com/docs/guides/embeddings
  10. Cohere Embed Documentation - https://docs.cohere.com/reference/embed
  11. HNSW原論文 - https://arxiv.org/abs/1603.09320
  12. Product Quantization論文 - https://hal.inria.fr/inria-00514462v2/document
  13. MTEB Leaderboard - https://huggingface.co/spaces/mteb/leaderboard
  14. Reciprocal Rank Fusion論文 - https://plg.uwaterloo.ca/~gvcormac/cormacksigir09-rrf.pdf

현재 단락 (1/513)

従来のデータベースは正確なキーワードマッチングに基づいています。「子犬(こいぬ)が公園(こうえん)で遊(あそ)んでいる」で検索すると、「犬(いぬ)が芝生(しばふ)で走(はし)っている」は見つかりません...

작성 글자: 0원문 글자: 17,594작성 단락: 0/513