Home 論文解説: Survey of Vector Database Management Systems
投稿
キャンセル

📄 論文解説: Survey of Vector Database Management Systems

論文概要(Abstract)

本論文は、ベクトルデータベース管理システム(Vector DBMS)を体系的にサーベイした包括的な研究です。近年のLLM・RAGパイプラインの普及に伴い急増するベクトル検索需要に対し、ストレージ管理・インデックス構造・クエリ処理・システムアーキテクチャの4軸で主要なベクトルDBを分類・比較しています。pgvector、Milvus、Qdrant、Pinecone、Weaviate、Chroma等を同一基準で評価し、HNSW・IVF・PQ等のANNアルゴリズムの性能特性を実測データとともに整理しています。

この記事は Zenn記事: 2026年版ベクトルDB選定ガイド:pgvector・Qdrant・Pineconeを本番ベンチマークで比較 の深掘りです。

情報源

背景と動機(Background & Motivation)

大規模言語モデル(LLM)とRetrieval-Augmented Generation(RAG)の急速な普及により、高次元ベクトルデータを効率的に格納・検索するシステムの需要が爆発的に増加しています。従来のリレーショナルDBでは、数百〜数千次元のベクトルに対するコサイン類似度やL2距離に基づく近傍検索を効率的に処理できません。

この課題に対し、専用ベクトルDB(Milvus、Qdrant)、既存DB拡張(pgvector、Elasticsearch)、マネージドサービス(Pinecone)といった多様なアプローチが登場しましたが、各システムの設計思想・性能特性・トレードオフを統一的に整理した研究は限られていました。本論文はこのギャップを埋める初の包括的サーベイです。

主要な貢献(Key Contributions)

  • 統一的な分類フレームワーク: ベクトルDBを「ストレージ管理」「インデックス構造」「クエリ処理」「システムアーキテクチャ」の4軸で体系的に分類
  • ANNアルゴリズムの比較分析: HNSW、IVF、PQ(Product Quantization)、DiskANN等の主要アルゴリズムをRecall-QPS-メモリ使用量の3指標で比較
  • 実測ベンチマーク: SIFT1M(128次元、100万件)、GloVe-100、Deep1Bなどの標準データセットでの性能比較データを集約
  • 設計トレードオフの明確化: インメモリ vs ディスクベース、単一ノード vs 分散、静的 vs 動的データの各軸でのトレードオフを体系化

技術的詳細(Technical Details)

ベクトルDBの4層アーキテクチャ

本論文はベクトルDBを以下の4層で分析しています。

Layer 1: ストレージ管理

ベクトルデータの格納方式には大きく3つのアプローチがあります。

インメモリ格納: すべてのベクトルをRAM上に保持。QdrantやMilvus(メモリモード)が採用。最高のレイテンシ性能を実現できますが、データ量がメモリ容量に制約されます。

ディスクベース格納: SSD上にベクトルを格納し、メモリにはインデックスのみを保持。DiskANNが代表的です。10億件規模のデータを64GB程度のメモリで処理可能ですが、SSDのランダムアクセス性能に依存します。

ハイブリッド格納: pgvectorやWeaviateが採用するアプローチ。頻繁にアクセスされるベクトルをメモリにキャッシュし、残りはディスクに格納します。

Layer 2: インデックス構造

ANNアルゴリズムは性能特性が大きく異なります。

HNSW(Hierarchical Navigable Small World):

グラフベースのインデックスで、現在最も広く使われています。多層グラフ構造を構築し、上位層で粗い近傍探索、下位層で精密な探索を行います。

構築時の計算量は以下の通りです:

\[O(N \cdot M \cdot \log N)\]

ここで、

  • $N$: データ数
  • $M$: グラフの最大次数(エッジ数)。典型値は16〜64

検索時の計算量は:

\[O(M \cdot \log N \cdot ef)\]
  • $ef$: 検索時の探索幅。大きいほどRecallが向上するがレイテンシが増加

HNSWの主要パラメータと推奨値:

パラメータ意味推奨値影響
$M$グラフ次数16〜64メモリ使用量とRecallのトレードオフ
$ef_construction$構築時の探索幅100〜200構築時間とインデックス品質
$ef_search$検索時の探索幅50〜200レイテンシとRecallのトレードオフ

IVF(Inverted File Index):

ベクトル空間をk-meansクラスタリングで$C$個のセルに分割し、クエリに近いセルのみを探索します。

\[\text{Recall} \approx 1 - \left(1 - \frac{n\_probe}{C}\right)^k\]
  • $C$: クラスタ数(典型値: $\sqrt{N}$)
  • $n_probe$: 探索するクラスタ数

IVFの利点はメモリ効率の良さですが、高次元データではクラスタ境界付近のベクトルで精度が低下します。

PQ(Product Quantization):

高次元ベクトルを低次元のサブベクトルに分割し、各サブベクトルをコードブックで量子化します。

\[\mathbf{x} \approx [q_1(\mathbf{x}^{(1)}), q_2(\mathbf{x}^{(2)}), \ldots, q_m(\mathbf{x}^{(m)})]\]
  • $\mathbf{x}^{(i)}$: $i$番目のサブベクトル($D/m$次元)
  • $q_i$: $i$番目のサブ量子化器($k$個のセントロイド)
  • メモリ削減率: $D \times 4$ bytes → $m \times \lceil\log_2 k\rceil$ bits

768次元ベクトルの場合、PQにより元のfloat32表現(3072 bytes)を96 bytes程度まで圧縮できます(32倍の圧縮)。

Layer 3: クエリ処理

フィルタ付きベクトル検索は、実務で最も重要な機能の一つです。メタデータ条件(例: category = "tech", date >= "2024-01-01")とベクトル類似度を組み合わせた検索です。

処理戦略は3つあります:

  1. Pre-filtering: メタデータフィルタを先に適用し、残ったベクトルに対してANN検索。フィルタ比率が小さい場合に非効率
  2. Post-filtering: ANN検索の結果にメタデータフィルタを適用。Recallが低下するリスク
  3. In-filter search: ANNアルゴリズム内でフィルタを統合。Qdrantが採用するFilterable HNSWが代表例

Layer 4: システムアーキテクチャ

スタンドアロン型: pgvector(PostgreSQL拡張)、Chroma。既存DBに統合されるため運用コストが低い 分散型: Milvus、Qdrant(クラスタモード)。シャーディングとレプリケーションでスケールアウト サーバーレス型: Pinecone。インフラ管理が不要だが、ベンダーロックインのリスク

主要DBの機能比較

機能pgvectorQdrantMilvusPineconeWeaviate
ANNHNSW, IVFFlatHNSWHNSW, IVF, DiskANN独自HNSW
フィルタWHERE句Filterable HNSW属性フィルタメタデータフィルタBM25+Dense
分散リードレプリカネイティブネイティブサーバーレスネイティブ
ストレージディスク+キャッシュメモリ+mmapメモリ/ディスクマネージドメモリ+ディスク
言語CRustGo/C++-Go
ライセンスPostgreSQLApache 2.0Apache 2.0プロプライエタリBSD-3

実装のポイント(Implementation)

HNSWパラメータチューニングの実践

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# pgvector でのHNSWインデックス作成例
# M=16: メモリ使用量を抑えつつ高いRecallを維持するバランスポイント
# ef_construction=200: 構築に時間をかけてインデックス品質を向上
import psycopg
from pgvector.psycopg import register_vector

conn = psycopg.connect("postgresql://user:pass@localhost/mydb")
register_vector(conn)

# HNSW インデックス作成
conn.execute("""
    CREATE INDEX IF NOT EXISTS idx_docs_hnsw
    ON documents USING hnsw (embedding vector_cosine_ops)
    WITH (m = 16, ef_construction = 200)
""")

# 検索時のefパラメータ設定(セッション単位)
conn.execute("SET hnsw.ef_search = 100")

# コサイン類似度検索
query_vec = get_embedding("検索クエリ")
results = conn.execute(
    "SELECT id, content, 1 - (embedding <=> %s::vector) AS similarity "
    "FROM documents ORDER BY embedding <=> %s::vector LIMIT 10",
    [query_vec, query_vec],
).fetchall()

Qdrant でのフィルタ付き検索

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from qdrant_client import QdrantClient
from qdrant_client.models import (
    Filter, FieldCondition, MatchValue, Range
)

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

# Filterable HNSW: フィルタとANNを同時に処理
results = client.query_points(
    collection_name="documents",
    query=get_embedding("検索クエリ"),
    query_filter=Filter(
        must=[
            FieldCondition(
                key="category",
                match=MatchValue(value="tech")
            ),
            FieldCondition(
                key="published_at",
                range=Range(gte="2024-01-01")
            ),
        ]
    ),
    limit=10,
    with_payload=True,
)

Recall-QPS トレードオフの可視化

Recall@10とQPSのトレードオフは、ANNアルゴリズムとパラメータ選択に大きく依存します。

設定Recall@10QPSメモリ(GB)用途
HNSW (M=16, ef=50)0.922,5004.2リアルタイム検索
HNSW (M=32, ef=100)0.971,2007.8高精度検索
HNSW (M=64, ef=200)0.9945015.2最高精度
IVF (C=1024, nprobe=16)0.855,0001.8高スループット
IVFPQ (C=1024, m=32)0.788,0000.6メモリ制約環境

Production Deployment Guide

AWS実装パターン(コスト最適化重視)

トラフィック量別の推奨構成:

規模月間リクエスト推奨構成月額コスト主要サービス
Small~3,000 (100/日)Serverless$50-150Lambda + Bedrock + DynamoDB
Medium~30,000 (1,000/日)Hybrid$300-800ECS Fargate + Aurora pgvector
Large300,000+ (10,000/日)Container$2,000-5,000EKS + Qdrant Cluster + ElastiCache

Small構成の詳細(月額$50-150):

  • Aurora Serverless v2 (PostgreSQL 16 + pgvector): 0.5〜1 ACU ($43/月)
  • Lambda: 検索API、1GB RAM ($20/月)
  • API Gateway: REST API ($5/月)
  • CloudWatch: 基本監視 ($5/月)

Medium構成の詳細(月額$300-800):

  • Aurora PostgreSQL r6g.large + pgvector: 2 vCPU, 16GB RAM ($200/月)
  • ECS Fargate: 検索サービス 0.5 vCPU, 1GB RAM × 2タスク ($120/月)
  • ElastiCache Redis (cache.t3.micro): クエリキャッシュ ($15/月)
  • Application Load Balancer: ($20/月)

Large構成の詳細(月額$2,000-5,000):

  • EKS: コントロールプレーン ($72/月)
  • Qdrant on EC2 Spot (r6i.xlarge × 3): 分散クラスタ ($600/月、Spot 70%割引適用)
  • Aurora PostgreSQL r6g.2xlarge: メタデータ格納 ($400/月)
  • ElastiCache Redis (cache.r6g.large): ベクトルキャッシュ ($200/月)
  • EC2 Spot Instances (Karpenter管理): 推論ワーカー ($800/月)

コスト削減テクニック:

  • Spot Instances使用で最大90%削減(EKS + Karpenter管理)
  • Aurora Serverless v2でアイドル時に自動スケールダウン
  • ElastiCacheでホットクエリをキャッシュし、DB負荷を80%削減
  • Savings Plans (1年コミット)で最大72%削減

コスト試算の注意事項:

  • 上記は2026年2月時点のAWS ap-northeast-1(東京)リージョン料金に基づく概算値です
  • 実際のコストはトラフィックパターン、ベクトル次元数、データ量により変動します
  • 最新料金は AWS料金計算ツール で確認してください

Terraformインフラコード

Small構成 (Serverless): Aurora pgvector + Lambda

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# --- VPC基盤 ---
module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "~> 5.0"

  name = "vectordb-vpc"
  cidr = "10.0.0.0/16"
  azs  = ["ap-northeast-1a", "ap-northeast-1c"]
  private_subnets  = ["10.0.1.0/24", "10.0.2.0/24"]
  database_subnets = ["10.0.3.0/24", "10.0.4.0/24"]

  enable_nat_gateway   = false
  enable_dns_hostnames = true
}

# --- Aurora Serverless v2 (pgvector) ---
resource "aws_rds_cluster" "vectordb" {
  cluster_identifier = "vectordb-cluster"
  engine             = "aurora-postgresql"
  engine_version     = "16.4"
  engine_mode        = "provisioned"

  database_name   = "vectordb"
  master_username = "dbadmin"
  master_password = aws_secretsmanager_secret_version.db_password.secret_string

  db_subnet_group_name   = aws_db_subnet_group.vectordb.name
  vpc_security_group_ids = [aws_security_group.aurora.id]

  serverlessv2_scaling_configuration {
    min_capacity = 0.5
    max_capacity = 4.0
  }

  storage_encrypted = true
}

resource "aws_rds_cluster_instance" "vectordb" {
  cluster_identifier = aws_rds_cluster.vectordb.id
  instance_class     = "db.serverless"
  engine             = aws_rds_cluster.vectordb.engine
  engine_version     = aws_rds_cluster.vectordb.engine_version
}

# --- Lambda関数 ---
resource "aws_lambda_function" "vector_search" {
  filename      = "lambda.zip"
  function_name = "vector-search-handler"
  role          = aws_iam_role.lambda_role.arn
  handler       = "index.handler"
  runtime       = "python3.12"
  timeout       = 30
  memory_size   = 1024

  environment {
    variables = {
      DB_HOST        = aws_rds_cluster.vectordb.endpoint
      DB_NAME        = "vectordb"
      DB_SECRET_ARN  = aws_secretsmanager_secret.db_password.arn
    }
  }

  vpc_config {
    subnet_ids         = module.vpc.private_subnets
    security_group_ids = [aws_security_group.lambda.id]
  }
}

# --- CloudWatch アラーム ---
resource "aws_cloudwatch_metric_alarm" "aurora_cpu" {
  alarm_name          = "aurora-cpu-high"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = 2
  metric_name         = "CPUUtilization"
  namespace           = "AWS/RDS"
  period              = 300
  statistic           = "Average"
  threshold           = 80
  alarm_description   = "Aurora CPU使用率80%超過"

  dimensions = {
    DBClusterIdentifier = aws_rds_cluster.vectordb.cluster_identifier
  }
}

Large構成 (Container): EKS + Qdrant Cluster

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# --- EKSクラスタ ---
module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "~> 20.0"

  cluster_name    = "vectordb-cluster"
  cluster_version = "1.31"

  vpc_id     = module.vpc.vpc_id
  subnet_ids = module.vpc.private_subnets

  cluster_endpoint_public_access = true
  enable_cluster_creator_admin_permissions = true
}

# --- Karpenter (Spot優先) ---
resource "kubectl_manifest" "karpenter_nodepool" {
  yaml_body = <<-YAML
    apiVersion: karpenter.sh/v1beta1
    kind: NodePool
    metadata:
      name: qdrant-nodes
    spec:
      template:
        spec:
          requirements:
            - key: karpenter.sh/capacity-type
              operator: In
              values: ["spot", "on-demand"]
            - key: node.kubernetes.io/instance-type
              operator: In
              values: ["r6i.xlarge", "r6i.2xlarge", "r7i.xlarge"]
          nodeClassRef:
            name: default
      limits:
        cpu: "64"
        memory: "256Gi"
      disruption:
        consolidationPolicy: WhenEmpty
        consolidateAfter: 30s
  YAML
}

# --- AWS Budgets ---
resource "aws_budgets_budget" "vectordb" {
  name         = "vectordb-monthly"
  budget_type  = "COST"
  limit_amount = "5000"
  limit_unit   = "USD"
  time_unit    = "MONTHLY"

  notification {
    comparison_operator       = "GREATER_THAN"
    threshold                 = 80
    threshold_type            = "PERCENTAGE"
    notification_type         = "ACTUAL"
    subscriber_email_addresses = ["ops@example.com"]
  }
}

セキュリティベストプラクティス

  • ネットワーク: Aurora/Qdrantはプライベートサブネットに配置、VPCエンドポイント経由でアクセス
  • 認証: IAM認証 + Secrets Manager、環境変数へのハードコード禁止
  • 暗号化: Aurora KMS暗号化(保管時)、TLS 1.3(転送時)
  • 監査: CloudTrail全リージョン有効化、Config変更追跡

運用・監視設定

1
2
3
4
-- CloudWatch Logs Insights: ベクトル検索レイテンシ分析
fields @timestamp, query_vector_dim, recall, latency_ms
| stats pct(latency_ms, 95) as p95, pct(latency_ms, 99) as p99 by bin(5m)
| filter latency_ms > 100
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import boto3

cloudwatch = boto3.client('cloudwatch')

# Aurora pgvector 検索レイテンシアラート
cloudwatch.put_metric_alarm(
    AlarmName='vectordb-search-latency-p99',
    ComparisonOperator='GreaterThanThreshold',
    EvaluationPeriods=2,
    MetricName='ReadLatency',
    Namespace='AWS/RDS',
    Period=300,
    Statistic='p99',
    Threshold=0.1,  # 100ms
    AlarmDescription='ベクトル検索p99レイテンシ100ms超過'
)

コスト最適化チェックリスト

  • ~100 req/日 → Aurora Serverless v2 + Lambda ($50-150/月)
  • ~1,000 req/日 → Aurora Provisioned + ECS Fargate ($300-800/月)
  • 10,000+ req/日 → EKS + Qdrant Cluster + Spot ($2,000-5,000/月)
  • EC2 Spot Instances優先(Karpenter自動管理で最大90%削減)
  • Aurora Serverless v2でアイドル時0.5 ACUまでスケールダウン
  • ElastiCacheでホットクエリキャッシュ(DB負荷80%削減)
  • Reserved Instances 1年コミット(72%削減)
  • Savings Plans検討(柔軟性重視の場合)
  • pgvectorのef_searchを用途別に調整(リアルタイム: 50、バッチ: 200)
  • IVFFlat→HNSWへの移行でRecall向上(メモリ増の代わり)
  • PQ(Product Quantization)でメモリ使用量を1/4〜1/32に圧縮
  • 不要なインデックスの定期的な削除
  • CloudWatch Anomaly Detectionでコスト異常の自動検知
  • タグ戦略: env/project/teamでコスト可視化
  • 開発環境のAurora Serverlessは夜間0 ACUに自動スケールダウン
  • S3へのベクトルバックアップにライフサイクルポリシー設定(30日でGlacier)
  • VPCエンドポイント使用でNAT Gateway通信料を削減
  • Lambda Provisioned Concurrencyは不要なら無効化
  • データパーティショニングで検索対象を絞り込み(日付・カテゴリ別)
  • ベクトル次元数の最適化(1536→768次元への次元削減でコスト半減)

実験結果(Results)

本論文で集約されたベンチマーク結果を要約します。

SIFT1M(128次元、100万件)での比較

インデックスRecall@10QPSメモリ(GB)ビルド時間
HNSW (M=16)0.971,8000.845秒
IVFFlat (C=256)0.893,2000.512秒
IVFPQ (C=256, m=16)0.726,5000.1530秒

高次元データ(768次元、100万件)での影響

次元数の増加により、すべてのアルゴリズムでQPSが低下しますが、HNSWの低下率が最も小さく、高次元でも安定した性能を維持します。IVFは次元数に比例して精度が低下する傾向があります。

実運用への応用(Practical Applications)

Zenn記事で紹介した「ステージ別選定フレームワーク」は、本論文の分類と整合しています。

MVPフェーズ(〜1Mベクトル): pgvectorが最適。既存PostgreSQLスタックにCREATE EXTENSION vectorを追加するだけで開始できます。HNSWインデックスにより、100万件程度であれば数百QPS以上の性能が得られます。

成長フェーズ(1M〜10M): フィルタ付き検索の要件が増える段階。QdrantのFilterable HNSWが真価を発揮します。Rust実装によるメモリ効率の良さも、この規模で重要になります。

大規模フェーズ(10M+): Milvusの分散アーキテクチャが適合。シャーディングとレプリケーションにより、水平スケーリングが可能です。

関連研究(Related Work)

  • ANN-Benchmarks (Aumüller et al., 2020): ANNアルゴリズムの標準ベンチマークフレームワーク。本論文はこれを拡張し、ベクトルDB全体を評価対象としている
  • Milvus: A Purpose-Built Vector Data Management System (Wang et al., 2021): Milvusの設計論文。本サーベイでは他DBとの比較文脈で引用
  • Efficient and Robust Approximate Nearest Neighbor Search (Fu et al., 2019): NSGグラフベースANNの提案。HNSWとの性能比較が本論文でも参照

まとめと今後の展望

本論文は、ベクトルDB選定の際の意思決定を体系化する重要な参考文献です。HNSW・IVF・PQ等のANNアルゴリズムの特性理解と、各DBの設計思想(スタンドアロン/分散/サーバーレス)の把握が、適切な選定の鍵となります。

今後の研究方向として、動的データに対するインデックス更新の効率化、フィルタ付き検索の最適化、マルチモーダルベクトル(テキスト+画像+音声)の統合検索が挙げられています。

参考文献

この投稿は CC BY 4.0 でライセンスされています。

論文解説: TextGrad — テキスト自動微分によるLLMパイプライン最適化フレームワーク

論文解説: When Better Prompts Hurt — 評価駆動プロンプト開発(EDPD)フレームワーク