"RAG 핵심 학습 (9/26) — 벡터DB 비교: FAISS / Chroma / Qdrant / Milvus / Weaviate / Pinecone / pgvector"
임베딩이 정해졌다면, 그 벡터를 어디에 저장할 것인가가 다음 결정이다.
벡터DB 선택은 바꾸기 어려운 결정이다. 인덱스 포맷·API·운영 모델이 모두 다르고, 마이그레이션은 재인덱싱을 부른다. 본 편은 2026년 기준 7개 주류 — FAISS / Chroma / Qdrant / Milvus / Weaviate / Pinecone / pgvector — 을 ANN 알고리즘(HNSW/IVF), metadata filter 표현력, update/delete 지원, 운영 비용·관리 부담 4축으로 비교한다. 7편 메타데이터 설계가 각 DB의 실제 지원과 어떻게 만나는지가 핵심.
0. Prerequisites
- 7편 메타데이터 — pre/post filter 구분, 카디널리티.
- 8편 임베딩 — 벡터 차원이 저장·latency에 미치는 영향.
- ANN(Approximate Nearest Neighbor)은 정확한 KNN을 포기하고 속도를 얻는 알고리즘이라는 사실.
1. 학습 목표
- HNSW / IVF / FLAT의 한 줄 차이를 안다.
- 7개 벡터DB의 선택 기준을 표로 안다.
- metadata filter 표현력이 7편 설계와 어떻게 만나는지 안다.
- update/delete가 RAG 운영에서 결정적인 이유를 안다.
2. 핵심 요약
벡터DB의 본질은 ANN 인덱스 + metadata 필터 + 운영 API다. FAISS는 라이브러리 — 빠르지만 DB가 아니다. Chroma는 로컬 prototyping 표준. Qdrant는 Rust 기반 self-host의 표준, payload 필터 표현력 최강. Milvus는 대규모·분산 운영용. Weaviate는 모듈러 + GraphQL + RBAC. Pinecone은 완전 매니지드 SaaS, 가장 빠른 셋업. pgvector는 PostgreSQL 확장, 기존 DB 운영에 가장 적합. 선택 기준 세 줄: 완전 매니지드 + 즉시 시작 → Pinecone, self-host + 기능 풍부 → Qdrant 또는 Milvus, 기존 Postgres + 작은 규모 → pgvector. ANN 알고리즘은 대부분 HNSW가 기본 — Filtered HNSW 또는 Hierarchical IVF로 metadata filter와 결합하는지가 결정적.
3. 직관 — 같은 코퍼스, 7개 다른 운영
같은 1M 청크·1024차원 코퍼스를 7개 도구에 넣으면 셋업 시간·운영 비용·필터 지원·재해 복구가 모두 다르다.
7개 모두 retrieval은 가능하다. 차이는 운영이다 — 누가 관리하는가, 어떻게 백업·복구하는가, 필터를 어디까지 표현할 수 있는가.
4. 정의 — 7개 주류 DB 비교 표 (2026년)
필터 표현력은 0~3 스케일 — 0=없음, 1=약함, 2=중간, 3=강함.
| DB | 형태 | ANN | metadata 필터 (0-3) | update/delete | 라이선스 | 운영 형태 |
|---|---|---|---|---|---|---|
| FAISS | 라이브러리 | HNSW, IVF, PQ | 0 (별도 IDList) | ❌ (재빌드) | MIT | 직접 코드 통합 |
| Chroma | 임베디드 DB | HNSW | 1 (dict 기반) | ✅ | Apache 2.0 | 로컬/self-host |
| Qdrant | 서버 | HNSW (Filtered) | 3 (payload, range/match) | ✅ | Apache 2.0 | self-host or cloud |
| Milvus | 서버 (분산) | HNSW, IVF, DiskANN | 2 (boolean, range) | ✅ | Apache 2.0 | self-host (etcd+pulsar) |
| Weaviate | 서버 | HNSW | 3 (GraphQL, ABAC) | ✅ | BSD-3 | self-host or cloud |
| Pinecone | SaaS | proprietary (HNSW-like) | 3 (mongo-style) | ✅ | 상용 | 완전 매니지드 |
| pgvector | Postgres 확장 | HNSW, IVF-flat | 3 (SQL WHERE 전부) | ✅ (SQL UPDATE/DELETE) | PostgreSQL | 기존 Postgres에 추가 |
핵심 차이 — 얼마나 운영이 매니지드인가와 metadata 필터의 표현력. FAISS는 라이브러리라 DB 기능 자체가 없다.
5. 식 — ANN 인덱스의 trade-off
FLAT (정확 KNN):
$$\text{Query} = \mathcal{O}(N \cdot d), \quad \text{Build} = \mathcal{O}(N)$$
소규모(N < 100K)에선 충분. 큰 N에선 선형 비용.
HNSW (Hierarchical Navigable Small World):
$$\text{Query} \approx \mathcal{O}(\log N), \quad \text{Build} = \mathcal{O}(N \cdot M \cdot \log N), \quad \text{Memory} \approx N \cdot d \cdot 4 + N \cdot M \cdot 8$$
여기서 \(M\) = 노드당 이웃 수 (보통 16~64). recall ≥ 95% 보장하면서 latency를 수 ms로.
IVF (Inverted File Index):
$$\text{Query} \approx \mathcal{O}(n_{\text{probe}} \cdot \frac{N}{n_{\text{list}}}), \quad \text{Build} = \mathcal{O}(N \cdot n_{\text{list}})$$
\(n_{\text{list}}\) = 클러스터 수, \(n_{\text{probe}}\) = query 시 검사할 클러스터 수. 디스크 친화적, 대규모(>100M)에 강함.
선택 기준:
| 인덱스 | 적합 N | recall | latency | 메모리 |
|---|---|---|---|---|
| FLAT | < 100K | 100% | 느림 | 작음 |
| HNSW | 100K ~ 100M | 95~99% | 빠름 | 큼 (메모리 상주) |
| IVF + PQ | > 100M | 90~95% | 중간 | 작음 (압축) |
| DiskANN | > 1B | 90~97% | 중간 | 작음 (SSD 기반) |
대부분의 RAG는 < 100M chunks → HNSW가 기본값.
6. 원리 워크스루 — 같은 query를 7개 DB로
6.1 Chroma (로컬 prototyping)
import chromadb
client = chromadb.PersistentClient(path="./chroma_db")
col = client.get_or_create_collection("rag", metadata={"hnsw:space": "cosine"})
col.add(
ids=["c001", "c002"],
embeddings=[emb1, emb2],
metadatas=[{"version": "3.2", "security_level": "internal"}, ...],
documents=[chunk1, chunk2],
)
results = col.query(
query_embeddings=[query_emb],
n_results=5,
where={"security_level": {"$in": ["public", "internal"]}, "version": "3.2"},
)
장점: 즉시 시작. 단점: 분산 안 됨, 대규모(\(>\) 1M)에서 latency 저하.
6.2 Qdrant (Rust 서버, payload 필터 최강)
from qdrant_client import QdrantClient
from qdrant_client.models import PointStruct, Filter, FieldCondition, MatchValue
client = QdrantClient("localhost", port=6333)
client.upsert(collection_name="rag", points=[
PointStruct(id=1, vector=emb1, payload={"version": "3.2", "security_level": "internal"}),
])
hits = client.search(
collection_name="rag",
query_vector=query_emb,
query_filter=Filter(must=[
FieldCondition(key="version", match=MatchValue(value="3.2")),
FieldCondition(key="security_level", match=MatchValue(value="internal")),
]),
limit=5,
)
장점: Filtered HNSW — pre-filter가 ANN 검색과 동시에 작동. 범위 필터(Range), nested 필드, geo 모두 지원.
6.3 Pinecone (SaaS, namespace 분리)
from pinecone import Pinecone
pc = Pinecone(api_key=API_KEY)
index = pc.Index("rag")
index.upsert(
vectors=[("c001", emb1, {"version": "3.2", "security_level": "internal"})],
namespace="acme", # tenant_id를 namespace로 → 강한 격리
)
results = index.query(
namespace="acme",
vector=query_emb,
top_k=5,
filter={"security_level": {"$in": ["public", "internal"]}, "version": "3.2"},
include_metadata=True,
)
장점: 즉시 매니지드, namespace로 tenant 분리. 단점: 비용, vendor lock-in.
6.4 pgvector (Postgres 확장)
CREATE EXTENSION vector;
CREATE TABLE rag_chunks (
id TEXT PRIMARY KEY,
embedding vector(1024),
version TEXT,
security_level TEXT,
document_id TEXT,
chunk_text TEXT
);
CREATE INDEX ON rag_chunks USING hnsw (embedding vector_cosine_ops);
CREATE INDEX ON rag_chunks (security_level, version);
-- Query
SELECT id, document_id, chunk_text,
1 - (embedding <=> query_emb) AS similarity
FROM rag_chunks
WHERE security_level IN ('public', 'internal')
AND version = '3.2'
ORDER BY embedding <=> query_emb
LIMIT 5;
장점: SQL의 전 표현력 — JOIN, 트랜잭션, 백업, 권한 모두 기존 Postgres. 단점: 대규모에서 HNSW 메모리 압박, 튜닝 부담.
7. 변형과 사례
7.1 Filtered HNSW vs Post-filter HNSW
- 무엇이 바뀌나: ANN 그래프 탐색 중에 필터를 적용(Qdrant, Weaviate) vs ANN 후 candidate에 필터(FAISS, Chroma 일부).
- 왜 쓰나: 선택률이 낮을 때(권한 필터 등) post-filter는 candidate가 비는 사고. Filtered HNSW가 전 검색 공간을 의식해 selectivity 낮아도 안정.
- 무엇이 가능해졌나: 권한 + RAG가 empty rate 0으로 안정 운영.
- 어디에 적합한가: 멀티테넌트, 엄격한 권한, security_level 4단계 이상.
- 한계: Filtered HNSW는 인덱스 빌드가 더 무거움. Chroma는 미지원, FAISS는 별도 IDList 필요.
7.2 IVF + PQ — 대규모 코퍼스의 압축 인덱스
- 무엇이 바뀌나: PQ(Product Quantization)로 벡터를 8~16 bytes로 압축.
- 왜 쓰나: 1B chunks × 1024d = 4 TB(float32) → PQ로 16 GB. 메모리 fit 가능.
- 무엇이 가능해졌나: 대규모 검색을 비용 적정으로.
- 어디에 적합한가: Milvus의 IVF_PQ, FAISS의 IndexIVFPQ. > 100M chunks.
- 한계: recall 5~10%p 손실. Reranker(13편)로 보완.
7.3 DiskANN — SSD 기반 ANN
- 무엇이 바뀌나: 인덱스를 SSD에 두고 그래프 탐색.
- 왜 쓰나: 메모리 한계를 SSD로 우회.
- 무엇이 가능해졌나: 1B+ chunks를 단일 노드에서 검색.
- 어디에 적합한가: Milvus DiskANN, OpenSearch DiskANN.
- 한계: SSD I/O bound — NVMe 필수, HDD는 불가.
7.4 pgvector + 기존 RDB 통합
- 무엇이 바뀌나: 벡터 검색 결과를 SQL JOIN으로 원본 테이블과 즉시 결합.
- 왜 쓰나: 기존 OLTP 시스템에 RAG를 얹는 가장 자연스러운 통합.
- 무엇이 가능해졌나: 트랜잭션, 백업, 권한, 모니터링 모두 Postgres 표준.
- 어디에 적합한가: 소규모(\(<\) 10M), 기존 Postgres 운영팀.
- 한계: HNSW 메모리 압박. 별도 read replica 권장.
7.5 Hybrid serving — Pinecone + 자체 평가
- 무엇이 바뀌나: 프로덕션은 Pinecone, 평가/실험은 로컬 Chroma 또는 Qdrant.
- 왜 쓰나: 매니지드 비용을 프로덕션에만 한정.
- 무엇이 가능해졌나: 빠른 실험, 안정 운영의 양립.
- 어디에 적합한가: 스타트업 ~ 중견.
- 한계: 두 환경의 임베딩·청크 동기화 운영 부담.
8. 한계와 실패 양상
8.1 데이터 영속성 누락 — FAISS 함정
- 왜 본질적인가: FAISS는 라이브러리 — pickle 저장 안 하면 프로세스 종료 시 인덱스 증발. 7편 메타데이터도 별도 저장.
- 진단: 데모용 코드를 그대로 프로덕션에 옮기면 재시작 시 인덱스 0.
- 완화: FAISS는 프로토타입까지. 프로덕션은 Chroma 이상.
- 다음 편: 16편(실험 자동화 — FAISS in-memory eval).
8.2 update/delete 누락 — 인덱스 부패
- 왜 본질적인가: 문서 업데이트 시 옛 청크 삭제 누락하면 옛+새 동시 인덱스. 7편 8.4절(version 불일치)와 같은 사고.
- 진단: 같은
document_id에 다른version의 청크가 동시에 top-K. - 완화: atomic transaction (pgvector, Qdrant) 또는 staged blue-green 인덱스.
- 다음 편: 22편(RAG 운영).
8.3 카디널리티 폭주 — 메타데이터 인덱스 비대
- 왜 본질적인가: 7편 8.3절 — 고카디널리티 필드를 모두 인덱싱하면 메타데이터 인덱스가 벡터보다 큼.
- 진단: 인덱스 빌드 시간 비정상, 디스크 사용량 폭증.
- 완화: 인덱싱할 필드 선언적으로 선택. Qdrant·Pinecone은 인덱스 필드 명시.
- 다음 편: 16편(실험 자동화에서 카디널리티 모니터링).
8.4 분산 운영 부담 — Milvus/Weaviate 함정
- 왜 본질적인가: Milvus는 etcd + pulsar + MinIO + 5+ 서비스. 운영팀이 없으면 유지 자체가 부담.
- 진단: 작은 팀이 Milvus 자체 호스팅 → 장애 빈도·복구 시간 증가.
- 완화: < 1B chunks이고 SaaS 가능하면 Milvus Cloud 또는 Pinecone. self-host은 전담 인력이 있을 때만.
- 다음 편: 22편(RAG 운영 비용).
8.5 벤더 lock-in — Pinecone 함정
- 왜 본질적인가: Pinecone의 proprietary 인덱스 포맷은 export 어려움. 마이그레이션 = 전체 재인덱싱.
- 진단: 비용 증가 시 수개월 마이그레이션 필요.
- 완화: 임베딩은 별도 저장 — 객체 스토리지에 raw vector 백업. 마이그레이션 시 임베딩만 재사용.
- 다음 편: 16편(데이터 백업 패턴).
8.5 Common Pitfalls
- "FAISS가 빠르니까 프로덕션도 FAISS." — 8.1절. 영속성·필터·운영이 없음.
- "메타데이터 필터는 어디나 똑같다." — 도구별 표현력 차이 0~3. 7편 설계가 실제 통과하는지 검증.
- "Pinecone에 넣으면 끝." — 8.5절. 임베딩 raw 백업은 필수.
- "분산 = 안전." — 8.4절. 운영 인력 없이는 분산이 더 위험.
- "HNSW 기본값으로 충분." — \(M\),
ef_construction,ef_search3개 파라미터 튜닝이 recall·latency를 결정.
9. 정리된 결론
Q1. 7개 DB 중 완전 매니지드 + 즉시 시작은?
Pinecone. 셋업 시간 분 단위, 인프라 운영 0. Chapter: 4장, 7.5절.
Q2. Self-host + payload 필터 표현력이 가장 강한 DB는?
Qdrant. Rust 기반, Filtered HNSW로 pre-filter가 ANN과 동시 작동, 범위·nested 필드 지원. Chapter: 4장, 6.2절.
Q3. HNSW와 IVF의 선택 기준을 한 줄로 말하라.
\(N < 100M\)이면 HNSW(메모리 상주, 빠름), \(N > 100M\)이면 IVF+PQ 또는 DiskANN(압축·디스크). Chapter: 5장.
Q4. Filtered HNSW가 권한 필터에 결정적인 이유는?
post-filter는 candidate가 전부 권한 밖이면 답이 빔. Filtered HNSW는 ANN 탐색 중 필터를 적용해 empty rate 0. Chapter: 7.1절, 7편 8.1절.
Q5. 벤더 lock-in을 줄이는 가장 단순한 완화는?
임베딩 raw vector를 객체 스토리지에 별도 백업. 마이그레이션 시 청크·메타데이터와 결합해 재인덱싱만. Chapter: 8.5절.
10. 추가 학습
1차 자료
- Malkov, Y., Yashunin, D. Efficient and robust approximate nearest neighbor search using Hierarchical Navigable Small World graphs. TPAMI 2018. arXiv:1603.09320.
- Jégou, H. et al. Product Quantization for Nearest Neighbor Search. TPAMI 2011. (IVF+PQ 기초)
- Subramanya, S. J. et al. DiskANN: Fast Accurate Billion-point Nearest Neighbor Search on a Single Node. NeurIPS 2019.
- Pinecone. HNSW Internals 시리즈 블로그 (2024).
- Qdrant. Filtered HNSW: How payload filters integrate with ANN search (2023 blog).
공식 docs
- FAISS:
https://github.com/facebookresearch/faiss/wiki - Chroma:
https://docs.trychroma.com/ - Qdrant:
https://qdrant.tech/documentation/ - Milvus:
https://milvus.io/docs - Weaviate:
https://weaviate.io/developers/weaviate - Pinecone:
https://docs.pinecone.io/ - pgvector:
https://github.com/pgvector/pgvector
보조 자료
- 사용자 노트 8장 — 벡터DB.
- 사용자 노트 35장 6절 — Index Partitioning, Multi-collection.
Cheat Sheet
| 시나리오 | 1순위 | 2순위 | 비고 |
|---|---|---|---|
| 즉시 시작, 매니지드 | Pinecone | Weaviate Cloud | namespace로 tenant 분리 |
| self-host, 기능 풍부 | Qdrant | Weaviate | Filtered HNSW |
| 대규모 분산 | Milvus | Vespa | 운영팀 필수 |
| 기존 Postgres 통합 | pgvector | — | \(<\) 10M chunks |
| 로컬 prototyping | Chroma | FAISS | 프로덕션 이전 필요 |
| RBAC + GraphQL | Weaviate | — | 모듈러 ML |
| 임베디드 SDK | Chroma | FAISS | 라이브러리 형태 |
설계 원칙 한 줄: 운영 모델(매니지드 vs self-host) → 규모 → 필터 표현력 → 통합 환경 순으로 좁힌다.
Bridge — 다음 편
다음 — RAG 핵심 학습 (10/26) Dense Retrieval 깊이 다이브.
벡터DB가 정해졌으면, 그 안에서 어떤 검색 방식이 작동하는지를 본다. Dense Retrieval — Bi-encoder, DPR(Karpukhin 2020), query-document 비대칭, top-K, 유사도 함수 — 의 원리를 식과 코드로 푼다.
시리즈 전체 안내: 시리즈 목차
댓글
댓글 쓰기