핵심 요약
1억 벡터(차원 1024) RAG 워크로드를 세 제품에 똑같이 적재해 6개월 운영. 결론: 1억 미만은 pgvector, 강한 필터링·실시간 업데이트 많으면 Qdrant, 운영 최소화 우선이면 Pinecone.
1. 측정 환경
- 벡터 1억 (text-embedding-3-large, 1024d, 정규화)
- 메타데이터 평균 12개 필드 (3개 필터 자주 사용)
- 워크로드: 100 QPS read · 5 QPS write
- P95 latency 목표: 100ms
2. 핵심 비교
| 지표 | pgvector (PG18, HNSW) | Qdrant 1.10 | Pinecone Serverless |
| 인덱스 빌드 시간 | 14시간 | 4.2시간 | ~2시간 (관리됨) |
| P50 검색 | 22ms | 11ms | 14ms |
| P95 검색 | 74ms | 32ms | 38ms |
| P99 검색 | 180ms | 62ms | 78ms |
| recall@10 (params 비교) | 0.96 | 0.98 | 0.97 |
| 스토리지 | 540GB (압축 옵션) | 410GB (Scalar quant) | 관리됨 |
| 월 비용 | $640 (db 인스턴스) | $520 (self-host) / $1,200 (cloud) | $1,400 |
| 운영 부담 | 중 (DBA가 같이) | 중-상 | 최소 |
3. pgvector — "DB 한 곳"의 장점
- 같은 PG에 메타데이터·트랜잭션·기존 데이터
- SQL JOIN으로 사용자 권한·테넌트 분리 자연스러움
- HNSW는 PG18에서 안정. 1억 미만이면 충분
- 한계: 1억 초과 시 메모리 압박, write heavy에선 인덱스 갱신 부담
CREATE INDEX ON docs USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 200);
-- 검색
SELECT id, embedding <=> $1 AS dist
FROM docs
WHERE team_id = $2 AND archived = false
ORDER BY dist LIMIT 10;
4. Qdrant — 필터·실시간에 강함
- payload index로 메타필터링 + 벡터 동시 최적화
- 스칼라/프로덕트 양자화로 메모리·디스크 절약
- 실시간 upsert에 강함 (segment 머지 효율)
- self-host 가능 (cloud는 별도 가격)
// 필터 + 벡터 동시
const res = await client.search('docs', {
vector: embedding,
limit: 10,
filter: {
must: [
{ key: 'team_id', match: { value: teamId } },
{ key: 'archived', match: { value: false } },
],
},
})
5. Pinecone — 운영 최소
- 관리형, 스케일 자동
- Namespace로 멀티테넌트 격리
- Pinecone Serverless는 사용량 기반 — 폭증 시 비용 큼
- 온프레미스·VPC 옵션은 추가 요금
6. 정확도 튜닝 — 트레이드오프
| params | recall@10 | P50 |
| HNSW m=8, ef=64 | 0.91 | 9ms |
| HNSW m=16, ef=100 | 0.96 | 14ms |
| HNSW m=32, ef=200 | 0.98 | 28ms |
m·ef를 올리면 정확도↑·메모리↑·속도↓. 95% recall이 보통 합리적 타협.
7. 메모리·디스크
1억 × 1024d × float32 = 410GB. 인덱스 별도. RAM에 다 올리는 게 이상적이지만 비용. 양자화 옵션:
- Scalar quant: float32 → int8 (4배 절감, recall -1%p)
- Product quant: 8~16배 절감, recall -3~5%p
- Binary quant: 32배 절감, recall -8%p — 추천: 1차 후 reranking
8. 멀티테넌시 — 큰 차이
- pgvector: 같은 테이블 + team_id 컬럼 + 인덱스. SQL의 자연스러움
- Qdrant: collection 또는 payload filter. payload filter가 일반적
- Pinecone: namespace per tenant. 다른 모델
9. 비용 — 1억 벡터 + 100 QPS
| 서비스 | 월 |
| pgvector (Neon Scale) | $640 |
| Qdrant Cloud | $1,200 |
| Qdrant self-host (k8s 3 노드) | $520 + 운영 |
| Pinecone Serverless | $1,400 |
| Weaviate Cloud | $980 |
10. 결정 가이드
| 상황 | 추천 |
| 벡터 <1억 + 기존 PG 활용 | pgvector |
| 강한 메타필터 + 실시간 갱신 | Qdrant |
| 운영 인력 없음·SaaS 우선 | Pinecone |
| 벡터 >5억 + 저비용 | Qdrant self-host |
| 온프레미스 필수 | Qdrant or Milvus |
11. 흔한 함정
- "항상 cosine similarity": 정규화 벡터면 inner product가 더 빠름
- 인덱스 빌드 중 다운: 양자화 옵션 변경 시 재빌드. 무중단 패턴 필요
- recall만 보고 비교: 같은 recall에서 속도 비교가 진짜
- 차원 변경: 임베딩 모델 바꿀 거면 비용·재인덱스 비용 계산
참고
- github.com/pgvector/pgvector
- qdrant.tech/documentation
- docs.pinecone.io
댓글 0