키워드 검색이 대답하지 못하는 질문들
SELECT * FROM docs WHERE content LIKE '%비용 절감%'로는 "지출을 줄이는 방법"을 묻는 쿼리에 올바른 문서를 돌려줄 수 없다. 두 표현은 의미적으로 같지만 키워드가 다르기 때문이다.
벡터 데이터베이스는 이 문제를 해결하기 위해 등장했다. 텍스트·이미지·음성을 고차원 수치 벡터(임베딩)로 변환해 저장하고, 쿼리 벡터와 의미적으로 가장 가까운 벡터를 빠르게 검색한다. 이 챕터는 그 핵심 개념인 임베딩, 근사 최근접 이웃(ANN) 알고리즘, 그리고 주요 엔진의 설계 트레이드오프를 DBA·플랫폼 엔지니어 시각에서 정리한다.
임베딩(Embedding)이란 무엇인가
임베딩은 비정형 데이터(텍스트, 이미지, 오디오)를 고정 길이의 부동소수점 배열로 변환한 것이다. ML 모델(BERT, OpenAI text-embedding, CLIP 등)이 학습 과정에서 의미·문맥을 수치 공간에 인코딩한다.
"비용 절감" → [0.031, -0.142, 0.087, ..., 0.063] (768개 float32)
"지출을 줄이는 방법" → [0.028, -0.138, 0.091, ..., 0.059] (768개 float32)두 벡터의 거리가 매우 짧다 → 의미가 유사하다고 판단할 수 있다.
임베딩 특성
| 항목 | 설명 |
|---|---|
| 차원 수 | 모델마다 다름: 768d(BERT), 1536d(OpenAI ada-002), 3072d(text-embedding-3-large) |
| 저장 크기 | float32 기준: 768d = 3KB, 1536d = 6KB, 3072d = 12KB |
| 배치 생성 | 임베딩 생성 자체가 GPU 연산. 대규모 데이터는 배치 처리 필수 |
| 시간적 의미 없음 | 임베딩에는 타임스탬프가 의미 없다 (TSDB와 근본적으로 다른 워크로드) |
중요한 제약: 임베딩 모델을 교체하면 모든 벡터를 재생성해야 한다. 서로 다른 모델의 벡터는 공간 자체가 달라 비교할 수 없다. 이 비용을 과소평가하면 마이그레이션에서 운영 장애가 발생한다.
왜 B-Tree나 해시 인덱스로는 안 되는가
RDBMS의 B-Tree는 정렬 가능한 1D 키를 위해 설계되었다. 768차원 벡터 공간에는 "정렬"이 없다. 어떤 벡터가 "더 크다"고 정의할 수 없기 때문에 B-Tree로 범위 탐색을 할 수 없다.
정확한 최근접 이웃(Exact NN)은 모든 벡터와의 거리를 계산하는 완전 탐색이 유일한 방법이다.
완전 탐색 복잡도: O(n × d)
n = 벡터 수, d = 차원
예: 1억 개 × 768d × 4 bytes(float32) = 약 300GB 스캔 / 쿼리
→ 실시간 서비스에서는 불가능이 한계를 극복하기 위해 근사 최근접 이웃(ANN: Approximate Nearest Neighbor) 알고리즘이 개발되었다. 약간의 정확도(recall)를 포기하고 수백~수천 배의 속도를 얻는다.
ANN 알고리즘 심화
HNSW — Hierarchical Navigable Small World
HNSW는 오늘날 벡터 DB에서 가장 널리 쓰이는 알고리즘이다. 계층형 그래프 구조로 탐색 경로를 단계적으로 좁혀 간다.
HNSW 핵심 파라미터:
| 파라미터 | 역할 | 기본값 | 트레이드오프 |
|---|---|---|---|
M | 노드당 최대 연결 수 | 16 | 높을수록 recall↑, 메모리↑ |
ef_construction | 인덱스 빌드 시 후보 탐색 크기 | 200 | 높을수록 품질↑, 빌드 시간↑ |
ef_search | 쿼리 시 후보 탐색 크기 | 100 | 높을수록 recall↑, 쿼리 지연↑ |
강점: recall이 높고 쿼리 지연이 낮다. 필터링과의 조합이 가능하다. 약점: 메모리 사용량이 크다(벡터 개수 × M × 8~16 bytes). 인덱스 빌드 시 메모리가 전부 필요하다.
IVF — Inverted File Index
IVF는 먼저 전체 벡터를 k-means로 군집화해 nlist개의 클러스터를 만들고, 쿼리 시에는 가장 가까운 nprobe개 클러스터만 탐색한다.
인덱스 구조:
클러스터 1(센트로이드 c1): [v3, v17, v42, ...]
클러스터 2(센트로이드 c2): [v1, v8, v55, ...]
...
클러스터 k(센트로이드 ck): [v9, v23, v91, ...]
쿼리 벡터 q:
1. q와 모든 센트로이드 거리 계산 → 가장 가까운 nprobe개 클러스터 선택
2. 선택된 클러스터 내 벡터들만 정밀 비교| 파라미터 | 역할 | 설정 기준 |
|---|---|---|
nlist | 클러스터 수 | 보통 sqrt(n) 부터 시작. 100만 벡터 → 1000 클러스터 |
nprobe | 탐색할 클러스터 수 | nlist의 5~20%. 높을수록 recall↑, 지연↑ |
강점: 메모리 효율이 좋다. 대규모 정적 데이터셋에 적합. 약점: 클러스터 경계 근처 벡터는 탐색에서 빠질 수 있다(recall 손실). 인덱스 빌드 전 데이터가 어느 정도 있어야 군집화가 의미있다.
PQ — Product Quantization (곱 양자화)
PQ는 인덱스 알고리즘이 아니라 압축 기법이다. HNSW나 IVF와 조합해(IVFPQ, HNSW+PQ) 메모리를 줄인다.
원리:
768차원 벡터를 M개의 서브벡터로 분할 (예: M=8 → 96차원씩 8 서브공간)
각 서브공간을 k(예: 256)개의 코드북으로 양자화
1536d float32(6KB) → M개의 1바이트 코드(8바이트) = 750× 압축
대가:
압축 과정에서 정보 손실 → recall 하락 (보통 2~5% p 하락)실제 운용에서는 IVFPQ 조합이 billion 규모의 벡터를 단일 서버에서 운용할 때 사용된다. Milvus가 내부적으로 지원하며, Faiss 라이브러리가 구현 기반이다.
DiskANN — SSD 기반 대규모 그래프
DiskANN은 Microsoft Research가 개발한 알고리즘으로, HNSW 수준의 recall을 유지하면서 벡터 데이터를 SSD에 저장한다. RAM 요구량이 원본 데이터의 10% 수준으로 줄어든다.
billion 규모 벡터를 단일 서버에서 처리하는 것이 목표다. Qdrant의 on-disk indexing, Azure AI Search 등이 이 개념을 채택했다.
거리 메트릭: 유사도를 측정하는 방법
| 메트릭 | 수식 | 언제 사용 | ||||
|---|---|---|---|---|---|---|
| 코사인 유사도 | `1 - (A·B / | A | B | )` | 텍스트 임베딩, 방향만 중요할 때 | |
| 유클리드 거리(L2) | sqrt(Σ(ai-bi)²) | 좌표 기반 공간, OpenAI 임베딩 | ||||
| 내적(Dot Product) | -(A·B) | 정규화된 벡터(코사인과 동일), 추천 시스템 |
실용 규칙: 임베딩 모델의 공식 문서가 권장하는 메트릭을 따른다. OpenAI의 text-embedding-3-*는 코사인 유사도 또는 정규화 후 내적을 권장한다. 잘못된 메트릭 선택은 recall을 10~20%p 이상 낮출 수 있다.
주요 엔진 비교
엔진 선택 기준
운영자 시각에서 가장 중요한 판단 기준은 현재 스택과의 통합 비용과 예상 데이터 규모다.
pgvector 선택 기준:
✓ 이미 PostgreSQL을 운영 중이다
✓ 벡터와 관계형 데이터를 JOIN해야 한다
✓ 벡터 수가 수백만 이하로 예상된다
✓ 새로운 인프라를 추가하지 않고 싶다
Qdrant 선택 기준:
✓ 페이로드(메타데이터) 필터링이 빈번하다 (예: 특정 사용자 문서만 검색)
✓ 수천만~수억 벡터 규모
✓ Self-hosting이 필요하다
✓ on-disk 인덱스로 RAM 비용을 줄여야 한다
Milvus 선택 기준:
✓ 수억~수십억 벡터 규모가 예상된다
✓ Kubernetes 인프라가 이미 있다
✓ 수평 확장이 필수다
✓ 다양한 인덱스 실험이 필요하다
Pinecone 선택 기준:
✓ 운영 인력이 없고 빠른 출시가 우선이다
✓ 데이터 주권 요건이 없다
✓ 벡터 DB 운영 복잡도를 피하고 싶다성능 기준선 (2024~2025 벤치마크 근사치)
| 엔진 | recall@10 | QPS (10M 벡터) | 메모리 (10M × 768d) |
|---|---|---|---|
| pgvector (HNSW) | 95~98% | 수백~수천 | 약 30GB |
| Qdrant (HNSW) | 97~99% | 수천~수만 | 약 25GB |
| Milvus (HNSW) | 97~99% | 수만+ | 약 25GB |
| Milvus (IVFPQ) | 90~95% | 수만+ | 약 2~4GB |
| Redis Vector (HNSW) | 95~98% | 수천~수만 | 약 30GB |
Open question: 벤치마크 결과는 하드웨어·파라미터·데이터 분포에 따라 크게 달라진다. 직접 representative dataset으로 측정 후 결정하는 것을 권장한다.
벡터 DB 운영의 핵심 메트릭
벡터 DB도 다른 TSDB·RDBMS처럼 운영 지표를 지속적으로 감시해야 한다.
| 지표 | 의미 | 임계값 |
|---|---|---|
| recall@k | 실제 최근접 이웃을 찾는 비율 | 서비스별 SLA 기준 (예: > 95%) |
| 쿼리 P99 지연 | 실제 사용자가 체감하는 최악의 응답 | < 100ms (실시간 서비스) |
| 인덱스 빌드 시간 | 새 벡터 배치를 인덱스에 반영하는 시간 | SLA에 따라 결정 |
| 인덱스 크기 | RAM 또는 디스크 사용량 | 용량 계획 기준 |
| 벡터 수(ingestion rate) | 초당 삽입 벡터 수 | 시스템 한계 대비 80% |
recall 저하는 인덱스 파라미터 변경 또는 데이터 분포 변화(데이터 드리프트)로 발생한다. 정기적으로 ground truth 검색 결과와 비교해 recall을 측정해야 한다.
References
- HNSW: Efficient and Robust Approximate Nearest Neighbor Search Using Hierarchical Navigable Small World Graphs (Malkov & Yashunin, 2018)
- Faiss: A Library for Efficient Similarity Search (Johnson et al., Meta AI, 2017)
- pgvector: Open-source vector similarity search for Postgres
- Qdrant Documentation: Vector Search Engine
- Milvus Documentation: Cloud-native Vector Database
- Weaviate Documentation
- ANN Benchmarks: Approximate Nearest Neighbor Benchmark
- DiskANN: Fast Accurate Billion-point Nearest Neighbor Search on a Single Node (Microsoft Research, 2019)
- OpenAI: Text Embedding Models
- Pinecone: Learning Center — What is a Vector Database?