개요
| 항목 | Postgres + pgvector | NumPy 기반 in-memory |
|---|
| 방식 | DB에 벡터 저장 및 유사도 검색 | 메모리에 벡터를 직접 올리고 계산 |
| 주요 구성 | Postgres, pgvector 확장, SQL | Python, NumPy |
| 유사도 계산 | ORDER BY embedding <=> query (내장) | np.dot, np.linalg.norm |
1. 아키텍처 구성 비교
Postgres + pgvector
CREATE TABLE documents (
id UUID,
content TEXT,
embedding VECTOR(768)
);
SELECT * FROM documents
ORDER BY embedding <=> '[0.1, 0.2, ..., 0.9]'::vector
LIMIT 5;
NumPy 기반 in-memory
import numpy as np
doc_embeddings = np.array([[...], [...], ...]) # shape: (N, 768)
query_embedding = np.array([...])
scores = np.dot(doc_embeddings, query_embedding)
top_k = np.argsort(scores)[-5:]
2. 성능 비교
| 항목 | Postgres + pgvector | NumPy |
|---|
| 검색 속도 | O(log N) (Index 사용 시) | ❌ O(N) (전체 비교) |
| 초기 로딩 속도 | 빠름 (DB 사용) | 느림 (메모리 로딩 필요) |
| 대규모 벡터 검색 | Index (IVFFlat, HNSW) 사용 가능 | ❌ 느려짐 |
| 벡터 수백~수천 개 | ❌ 느림 (쿼리 오버헤드) | 매우 빠름 (RAM 내 연산) |
3. 유지보수 및 확장성
| 항목 | Postgres + pgvector | NumPy |
|---|
| 실시간 삽입/삭제 | SQL로 간편하게 가능 | ❌ 재배열 필요 (느림) |
| 영속성 | 영속 저장 | ❌ 휘발성 (RAM 기반) |
| 멀티 유저/서비스 | 트랜잭션 및 사용자 분리 | ❌ 단일 프로세스 전용 |
| 배포 환경 | 표준 SQL 스택 | ❌ Python 실행환경 필요 |
4. 실무 사용 사례
Postgres + pgvector가 적합한 경우
- 운영 서비스에서 대규모 문서 검색
- 검색 정확도와 속도 균형 필요
- 기존 Postgres 기반 인프라와 통합 필요
- 데이터 영속성 / 트랜잭션 관리가 필요한 경우
예: 고객 CS 대화 이력, 게시글 유사도 검색, FAQ 추천 시스템
NumPy가 적합한 경우
- 실험, R&D 또는 임시 시스템
- 수천 개 이하의 벡터를 자주 변경/튜닝
- Python 환경에서 전체 파이프라인 구성
- 빠른 프로토타이핑 / 벤치마킹 목적
예: LLM 프롬프트 튜닝 실험, Agent 간 메모리 공유, 프로토타이핑
비교 요약
| 항목 | Postgres + pgvector | NumPy in-memory |
|---|
| 🧠 초당 유사도 검색 속도 (100K 이상) | 인덱스 활용 | ❌ 느려짐 |
| 🚀 초기 학습/실험 | ❌ 복잡한 세팅 | 빠름 |
| 💾 영속성 & 유지보수 | 있음 | ❌ 없음 |
| 🔌 Python 연동성 | ❌ SQL 통신 필요 | 바로 연결 |
| 🧪 프롬프트 실험용 튜닝 | ❌ 느림 | 고속 벤치마킹 |
결론
| 상황 | 추천 방식 |
|---|
| 운영 서비스에서 대규모 검색이 필요 | Postgres + pgvector |
| 빠르게 LLM + 임베딩 실험을 하고 싶다 | NumPy 기반 in-memory |
| Agent memory, RAG tuning, eval loop | NumPy |
| 로그 기록, 버전관리, 권한 분리 필요 | pgvector |
- 개발 초기: NumPy 기반 실험 및 모델 튜닝
- 운영 이전: pgvector로 이전하여 서비스에 배포