Pinecone, Weaviate, Qdrant, pgvector 등 주요 벡터 데이터베이스의 특성을 비교하고 상황에 맞는 선택 가이드를 제공합니다.
벡터 데이터베이스(Vector Database)는 고차원 벡터를 효율적으로 저장하고 유사도 검색을 수행하는 전문 데이터베이스입니다. RAG 시스템에서 임베딩 모델이 생성한 벡터를 저장하고, 사용자 질문에 가장 관련성 높은 청크를 밀리초 단위로 검색하는 역할을 합니다.
전통적인 관계형 데이터베이스가 정확한 값 매칭(WHERE name = 'John')에 최적화되어 있다면, 벡터 데이터베이스는 근사 최근접 이웃 검색(Approximate Nearest Neighbor, ANN)에 최적화되어 있습니다. 수백만에서 수억 개의 벡터 중에서 주어진 쿼리 벡터와 가장 가까운 K개를 빠르게 찾아냅니다.
전통 DB: SELECT * FROM docs WHERE category = 'policy'
벡터 DB: query_vector에 가장 가까운 상위 5개 벡터 반환Pinecone은 완전 관리형(Fully Managed) 벡터 데이터베이스입니다. 인프라 관리가 전혀 필요 없으며, API 키를 발급받고 인덱스를 생성하면 바로 사용할 수 있습니다. 인덱스 크기 조정, 샤딩, 복제 등이 자동으로 처리됩니다.
from pinecone import Pinecone, ServerlessSpec
pc = Pinecone(api_key="your-api-key")
# 인덱스 생성
pc.create_index(
name="rag-knowledge-base",
dimension=1536,
metric="cosine",
spec=ServerlessSpec(
cloud="aws",
region="us-east-1"
)
)
index = pc.Index("rag-knowledge-base")
# 벡터 업서트
index.upsert(
vectors=[
{
"id": "doc-001",
"values": embedding_vector,
"metadata": {
"source": "company_policy.pdf",
"section": "휴가 정책",
"date": "2026-01-15"
}
}
],
namespace="policies"
)
# 검색
results = index.query(
vector=query_vector,
top_k=5,
include_metadata=True,
namespace="policies",
filter={"date": {"$gte": "2025-01-01"}}
)장점: 운영 부담 최소, 자동 스케일링, 메타데이터 필터링, 네임스페이스 기반 멀티테넌시
단점: 벤더 종속, 자체 호스팅 불가, 대규모 인덱스에서 비용 증가
Weaviate는 오픈소스 벡터 데이터베이스로, 자체 호스팅과 클라우드 서비스 모두 지원합니다. 특히 하이브리드 검색(벡터 + BM25)을 기본 내장하고 있으며, 임베딩 모듈을 통해 텍스트를 직접 넣으면 자동으로 벡터화하는 기능을 제공합니다.
import weaviate
from weaviate.classes.init import Auth
from weaviate.classes.query import MetadataQuery
client = weaviate.connect_to_weaviate_cloud(
cluster_url="your-cluster-url",
auth_credentials=Auth.api_key("your-api-key")
)
# 컬렉션 정의
collection = client.collections.create(
name="Document",
vectorizer_config=weaviate.classes.config.Configure.Vectorizer.text2vec_openai(
model="text-embedding-3-small"
),
properties=[
weaviate.classes.config.Property(
name="content", data_type=weaviate.classes.config.DataType.TEXT
),
weaviate.classes.config.Property(
name="source", data_type=weaviate.classes.config.DataType.TEXT
),
]
)
# 텍스트만 넣으면 자동으로 임베딩 생성
collection.data.insert(
properties={
"content": "재택근무는 주 2회까지 신청할 수 있습니다.",
"source": "hr_policy.pdf"
}
)
# 하이브리드 검색 (벡터 + BM25)
results = collection.query.hybrid(
query="재택근무 신청 방법",
limit=5,
alpha=0.7, # 0=순수 BM25, 1=순수 벡터
return_metadata=MetadataQuery(score=True)
)장점: 오픈소스, 하이브리드 검색 내장, 자동 벡터화, GraphQL API
단점: 자체 호스팅 시 운영 복잡도, 메모리 사용량이 높음
Qdrant는 Rust로 작성된 오픈소스 벡터 데이터베이스입니다. 높은 성능과 정교한 필터링 기능이 특징이며, 페이로드(Payload) 기반의 복잡한 조건부 검색을 효율적으로 처리합니다.
from qdrant_client import QdrantClient
from qdrant_client.models import (
Distance, VectorParams, PointStruct,
Filter, FieldCondition, MatchValue
)
client = QdrantClient(url="http://localhost:6333")
# 컬렉션 생성
client.create_collection(
collection_name="documents",
vectors_config=VectorParams(
size=1536,
distance=Distance.COSINE
)
)
# 벡터 업서트
client.upsert(
collection_name="documents",
points=[
PointStruct(
id=1,
vector=embedding_vector,
payload={
"content": "연차는 입사일 기준으로 부여됩니다.",
"source": "hr_policy.pdf",
"category": "휴가",
"year": 2026
}
)
]
)
# 필터링 검색
results = client.query_points(
collection_name="documents",
query=query_vector,
limit=5,
query_filter=Filter(
must=[
FieldCondition(
key="category",
match=MatchValue(value="휴가")
)
]
)
)장점: Rust 기반 고성능, 정교한 필터링, 낮은 메모리 사용량, 바이너리 양자화(Binary Quantization) 지원
단점: 하이브리드 검색을 위해 별도 설정 필요, 생태계가 상대적으로 작음
pgvector는 PostgreSQL의 확장(Extension)으로, 기존 PostgreSQL 데이터베이스에 벡터 검색 기능을 추가합니다. 이미 PostgreSQL을 사용하고 있는 팀에게는 별도의 벡터 데이터베이스를 도입하지 않아도 되므로, 운영 복잡도를 크게 줄일 수 있습니다.
-- pgvector 확장 설치
CREATE EXTENSION vector;
-- 벡터 컬럼이 있는 테이블 생성
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
content TEXT NOT NULL,
source TEXT,
category TEXT,
embedding vector(1536),
created_at TIMESTAMP DEFAULT NOW()
);
-- HNSW 인덱스 생성 (검색 성능 최적화)
CREATE INDEX ON documents
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 200);
-- 유사도 검색
SELECT id, content, source,
1 - (embedding <=> query_embedding) AS similarity
FROM documents
WHERE category = '휴가'
ORDER BY embedding <=> query_embedding
LIMIT 5;import psycopg2
from pgvector.psycopg2 import register_vector
conn = psycopg2.connect("postgresql://user:pass@localhost/mydb")
register_vector(conn)
cur = conn.cursor()
# 검색
cur.execute("""
SELECT id, content, 1 - (embedding <=> %s) AS similarity
FROM documents
ORDER BY embedding <=> %s
LIMIT 5
""", (query_vector, query_vector))
results = cur.fetchall()장점: 기존 PostgreSQL 인프라 활용, 트랜잭션 일관성, SQL 기반 복합 쿼리, 관계형 데이터와 벡터의 조인
단점: 수천만 벡터 이상 대규모에서 전용 벡터 DB 대비 성능 저하, HNSW 인덱스 빌드 시간이 김
pgvectorscale은 Timescale이 개발한 pgvector의 성능 확장으로, 대규모 벡터에서의 검색 속도를 크게 개선합니다. pgvector만으로 성능이 부족한 경우 검토해 볼 만한 선택지입니다.
벡터 데이터베이스의 검색 성능은 사용하는 인덱싱 알고리즘에 크게 좌우됩니다. 대표적인 두 가지 알고리즘을 살펴봅니다.
현재 가장 널리 사용되는 ANN 알고리즘입니다. 다층 그래프 구조를 구성하여, 상위 레이어에서 대략적인 탐색을 하고 하위 레이어로 내려가며 정밀하게 검색합니다.
HNSW 그래프 구조:
Layer 2: A -------- D (성긴 연결, 빠른 탐색)
Layer 1: A --- B --- D --- F (중간 밀도)
Layer 0: A-B-C-D-E-F-G-H-I (모든 노드, 정밀 검색)벡터 공간을 여러 클러스터로 분할하고, 검색 시 쿼리와 가까운 클러스터만 탐색하여 속도를 높입니다. HNSW보다 메모리 효율이 좋지만, 정확도와 속도의 트레이드오프를 클러스터 수(nlist)와 탐색 클러스터 수(nprobe)로 조절해야 합니다.
벡터 데이터베이스 선택을 위한 체계적인 의사결정 기준을 제시합니다.
| 상황 | 추천 | 이유 |
|---|---|---|
| 인프라 관리 인력 없음 | Pinecone | 완전 관리형, 운영 부담 최소 |
| 이미 PostgreSQL 사용 중 | pgvector | 추가 인프라 불필요, 트랜잭션 일관성 |
| 오픈소스 선호, 자체 호스팅 | Qdrant 또는 Weaviate | 제어권 확보, 벤더 종속 회피 |
| 하이브리드 검색 핵심 요구 | Weaviate | BM25 + 벡터 검색 기본 내장 |
| 복잡한 필터링 필요 | Qdrant | 페이로드 기반 정교한 필터링 |
| 벡터 수 | 추천 | 비고 |
|---|---|---|
| 10만 이하 | pgvector 또는 Chroma | 프로토타이핑에 적합 |
| 10만~1000만 | 모든 선택지 가능 | 요구사항에 따라 결정 |
| 1000만 이상 | Qdrant, Pinecone, Milvus | 대규모 최적화 필수 |
벡터 데이터베이스의 선택은 한 번 결정하면 변경하기 어렵습니다. 마이그레이션은 전체 재인덱싱을 의미하며, API 호환성도 보장되지 않습니다. PoC 단계에서 2~3개를 비교 평가한 후 결정하시기 바랍니다.
대규모 벡터 인덱스에서 저장 비용과 검색 속도를 최적화하기 위해 양자화(Quantization) 기법을 사용할 수 있습니다.
32비트 부동소수점 벡터를 8비트 정수로 변환합니다. 메모리 사용량이 4분의 1로 줄지만, 정확도 손실은 미미합니다.
각 차원을 1비트(0 또는 1)로 변환합니다. 메모리가 32분의 1로 줄지만, 정확도 손실이 있으므로 리랭킹과 함께 사용하는 것이 일반적입니다.
# Qdrant에서 바이너리 양자화 설정
from qdrant_client.models import (
BinaryQuantization,
BinaryQuantizationConfig
)
client.create_collection(
collection_name="documents_quantized",
vectors_config=VectorParams(
size=1536,
distance=Distance.COSINE
),
quantization_config=BinaryQuantization(
binary=BinaryQuantizationConfig(
always_ram=True # 양자화된 벡터를 항상 RAM에 유지
)
)
)벡터를 여러 서브벡터로 나누고, 각 서브벡터를 코드북의 가장 가까운 센트로이드로 대체합니다. 스칼라 양자화보다 더 높은 압축률을 달성할 수 있습니다.
LangChain은 주요 벡터 데이터베이스에 대한 통합 인터페이스를 제공합니다. 동일한 코드 구조로 데이터베이스만 교체하여 비교 평가할 수 있습니다.
from langchain.embeddings import OpenAIEmbeddings
from langchain.schema import Document
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
documents = [
Document(
page_content="연차는 입사일 기준으로 매년 15일이 부여됩니다.",
metadata={"source": "hr_policy.pdf", "category": "휴가"}
),
Document(
page_content="재택근무는 팀장 승인 후 주 2회까지 가능합니다.",
metadata={"source": "hr_policy.pdf", "category": "근무"}
),
]
# Pinecone
from langchain_pinecone import PineconeVectorStore
pinecone_store = PineconeVectorStore.from_documents(
documents, embeddings, index_name="rag-demo"
)
# Qdrant
from langchain_qdrant import QdrantVectorStore
qdrant_store = QdrantVectorStore.from_documents(
documents, embeddings,
url="http://localhost:6333",
collection_name="rag-demo"
)
# pgvector
from langchain_postgres import PGVector
pgvector_store = PGVector.from_documents(
documents, embeddings,
connection="postgresql://user:pass@localhost/mydb",
collection_name="rag-demo"
)
# 동일한 인터페이스로 검색
results = pinecone_store.similarity_search("연차 몇 일?", k=3)벡터 데이터베이스는 RAG 시스템의 검색 인프라입니다. Pinecone은 운영 부담 없는 관리형 서비스로, Weaviate는 하이브리드 검색이 내장된 유연한 오픈소스로, Qdrant는 고성능과 정교한 필터링으로, pgvector는 기존 PostgreSQL 인프라와의 통합으로 각각 강점을 가집니다. 운영 여건, 규모, 핵심 요구사항을 기준으로 선택하되, PoC 단계에서 충분한 비교 평가를 수행하시기 바랍니다.
다음 장에서는 지금까지 다룬 임베딩, 청킹, 벡터 데이터베이스를 조합하여 실제 동작하는 인덱싱 및 검색 파이프라인을 구축합니다.
이 글이 도움이 되셨나요?
문서 로딩부터 임베딩 생성, 벡터 저장, 유사도 검색까지 RAG 파이프라인의 전체 흐름을 실제 코드로 구현합니다.
RAG 검색 품질을 좌우하는 청킹 전략의 종류, 벤치마크 결과, 그리고 최적의 청크 크기를 선택하는 실전 가이드입니다.
키워드 기반 BM25와 벡터 기반 시맨틱 검색을 결합한 하이브리드 검색의 원리, 구현 방법, 그리고 Reciprocal Rank Fusion 전략을 다룹니다.