Summary
pgvector는 PostgreSQL에서 벡터 데이터를 저장하고 검색할 수 있게 해주는 오픈소스 익스텐션이다. HNSW(Hierarchical Navigable Small World) 알고리즘을 통해 빠른 ANN(Approximate Nearest Neighbor) 검색을 지원하며, PostgreSQL의 모든 기능(트랜잭션, JOIN, 집계)을 벡터 검색과 함께 활용할 수 있다는 점이 최대 강점이다. Qdrant, Milvus 같은 전용 벡터 DB 대비 운영 복잡도가 낮고, Full Text Search와 결합한 Hybrid Search를 SQL 네이티브로 구현할 수 있다.
pgvector란?
개념
pgvector는 PostgreSQL에 벡터 데이터 타입과 벡터 연산 기능을 추가하는 익스텐션이다. 기계학습 모델이 생성한 임베딩 벡터(embedding vector)를 데이터베이스에 저장하고, 코사인 유사도나 유클리디안 거리 같은 벡터 연산을 통해 의미적으로 유사한 데이터를 검색할 수 있게 해준다.
주요 특징:
- ✅ PostgreSQL 익스텐션으로 설치 간편
- ✅ 벡터 데이터 타입 지원 (
vector(n)
) - ✅ 다양한 거리 함수 (코사인, L2, 내적)
- ✅ HNSW 인덱스로 빠른 ANN 검색
- ✅ SQL 표준 문법으로 벡터 검색
- ✅ PostgreSQL의 모든 기능과 호환
왜 pgvector인가?
기존 벡터 DB의 한계:
문제 | 설명 | pgvector 해결 |
---|---|---|
분산된 데이터 | 벡터는 Qdrant, 메타데이터는 RDB | 단일 DB 통합 |
복잡한 쿼리 | JOIN, 집계 제한적 | SQL 모든 기능 활용 |
트랜잭션 부재 | 데이터 일관성 보장 어려움 | ACID 트랜잭션 지원 |
운영 복잡도 | 2개 DB 시스템 관리 | PostgreSQL 하나로 |
학습 곡선 | 새로운 API/쿼리 언어 | 익숙한 SQL 사용 |
pgvector의 강점:
- 🔗 통합: 벡터 + 메타데이터 + 관계형 데이터 한 곳에
- 💪 강력한 SQL: JOIN, 집계, 윈도우 함수 등 모두 사용 가능
- 🔒 트랜잭션: ACID 보장으로 데이터 무결성
- 💰 비용 효율: 별도 벡터 DB 불필요
- 📈 확장성: PostgreSQL의 성숙한 생태계 활용
벡터 데이터 타입
vector(n) 타입
pgvector는 고정 길이 벡터를 저장하는 vector(n)
타입을 제공한다.
테이블 구조 예시:
컬럼명 | 데이터 타입 | 설명 | 예시 |
---|---|---|---|
id | SERIAL | Primary Key | 1, 2, 3, … |
content | TEXT | 원본 텍스트 | ”PostgreSQL is powerful…“ |
embedding | vector(1536) | 임베딩 벡터 | [0.123, -0.456, 0.789, …] |
벡터 데이터 형식:
- 대괄호로 감싼 실수 배열:
'[0.1, 0.2, 0.3, ...]'
- 고정 길이: 정확히 선언한 차원수와 일치해야 함
- 실수 정밀도: 기본 float4 (32-bit)
지원 차원수:
- 최대 16,000 차원까지 지원
- 일반적인 임베딩 모델 차원수:
- OpenAI text-embedding-3-small: 1536
- OpenAI text-embedding-3-large: 3072
- Cohere embed-v3: 1024
- BGE-M3: 1024
거리 함수
pgvector는 세 가지 거리 함수를 제공한다.
연산자 | 거리 함수 | 사용 케이스 | 범위 |
---|---|---|---|
<-> | L2 (유클리디안) | 절대 거리 측정 | [0, ∞) |
<=> | 코사인 거리 | 방향 유사도 (텍스트) | [0, 2] |
<#> | 내적 (음수) | 벡터 곱 기반 유사도 | (-∞, ∞) |
거리 계산 방식:
연산 | SQL 표현식 | 결과 해석 | 사용 시기 |
---|---|---|---|
코사인 거리 | embedding <=> query | 0에 가까울수록 유사 | 대부분의 텍스트 검색 |
코사인 유사도 | 1 - (embedding <=> query) | 1에 가까울수록 유사 | 점수 표시 시 |
L2 거리 | embedding <-> query | 작을수록 가까움 | 절대 거리 중요 시 |
내적 | embedding <#> query | 클수록 유사 | 정규화된 벡터 |
정렬 및 필터링:
- 정렬:
ORDER BY embedding <=> query
(가장 유사한 순) - 임계값:
WHERE 1 - (embedding <=> query) > 0.7
(유사도 70% 이상) - 제한:
LIMIT 10
(상위 10개)
인덱스: HNSW 알고리즘
HNSW란?
**Hierarchical Navigable Small World (HNSW)**는 그래프 기반 ANN(Approximate Nearest Neighbor) 검색 알고리즘이다. 데이터 포인트들을 다층 그래프로 구성하여 빠른 근사 검색을 가능하게 한다.
작동 원리:
Layer 2 (상위): A ←→ B (성긴 연결, 빠른 탐색)
↓ ↓
Layer 1 (중간): A ←→ C ←→ B (중간 밀도)
↓ ↓ ↓
Layer 0 (하위): A-D-C-E-B-F-G (조밀한 연결, 정확한 검색)
검색 과정:
- 상위 레이어에서 대략적인 위치 빠르게 찾기
- 하위 레이어로 내려가며 정밀 탐색
- 가장 가까운 이웃을 효율적으로 발견
복잡도:
- 구축: O(n log n)
- 검색: O(log n) (vs Brute Force O(n))
- 공간: O(n × m)
HNSW 인덱스 생성
인덱스 생성 문법:
요소 | 값 | 설명 |
---|---|---|
인덱스 타입 | hnsw | Hierarchical Navigable Small World |
거리 함수 | vector_cosine_ops | 코사인 거리 (또는 vector_l2_ops) |
m 파라미터 | 16 | 그래프 연결성 (기본값) |
ef_construction | 64 | 구축 시 탐색 깊이 (기본값) |
파라미터 튜닝:
파라미터 | 설명 | 기본값 | 권장 범위 | 영향 |
---|---|---|---|---|
m | 그래프 연결성 | 16 | 8-64 | 높을수록 정확하지만 메모리↑ |
ef_construction | 구축 시 탐색 깊이 | 64 | 64-200 | 높을수록 정확하지만 구축 시간↑ |
ef_search | 검색 시 탐색 깊이 | 40 | 40-400 | 높을수록 정확하지만 검색 속도↓ |
데이터 규모별 권장 설정:
벡터 수 | m | ef_construction | ef_search | 특징 |
---|---|---|---|---|
< 10K | 8 | 64 | 40 | 빠른 구축, 소규모 데이터 |
10K-100K | 16 | 64 | 40 | 균형잡힌 성능 (기본) |
> 100K | 32 | 128 | 100 | 높은 정확도, 대규모 |
정확도 우선 | 64 | 256 | 200 | 최고 품질, 느림 |
런타임 조정:
ef_search
: 세션별로 검색 정확도 조정 가능- 기본값 40에서 100으로 증가 → 정확도 향상, 속도 감소
- 쿼리마다 다른 값 설정 가능
IVFFlat vs HNSW 비교
pgvector는 두 가지 인덱스 알고리즘을 지원한다.
특성 | IVFFlat | HNSW |
---|---|---|
알고리즘 | 클러스터링 기반 | 그래프 기반 |
구축 속도 | 빠름 | 느림 |
검색 속도 | 중간 | 매우 빠름 |
정확도 | 중간 (조정 가능) | 높음 |
메모리 | 적음 | 많음 |
권장 사용 | 대규모 데이터 (>1M) | 일반적인 경우 |
권장: 대부분의 경우 HNSW 사용. IVFFlat은 수백만 개 이상의 벡터에서 메모리 제약이 있을 때만 고려.
Hybrid Search: Dense + Sparse 결합
PostgreSQL FTS와의 결합
pgvector의 최대 강점은 PostgreSQL의 Full Text Search (FTS)와 결합한 Hybrid Search를 SQL 네이티브로 구현할 수 있다는 점이다.
Hybrid Search 전략:
검색 방식 | 기술 | 장점 | 단점 |
---|---|---|---|
Dense | pgvector (코사인 유사도) | 의미적 유사성 이해 | 키워드 정확 매칭 약함 |
Sparse | PostgreSQL FTS (BM25) | 키워드 정확 매칭 | 의미적 유사성 이해 불가 |
Hybrid | Dense + Sparse 결합 | 두 장점 모두 활용 | 구현 복잡도 증가 |
Reciprocal Rank Fusion (RRF)
Supabase가 권장하는 RRF 방식으로 Dense와 Sparse 결과를 결합한다.
RRF 공식:
RRF_score = Σ 1 / (k + rank_i)
Hybrid Search 프로세스:
단계 | 검색 방식 | 기술 | 결과 | RRF 점수 |
---|---|---|---|---|
1단계 | Dense Search | pgvector 코사인 유사도 | Top 20 | 1/(60+rank) |
2단계 | Sparse Search | PostgreSQL FTS (BM25) | Top 20 | 1/(60+rank) |
3단계 | 결과 결합 | FULL OUTER JOIN | 중복 제거 | Dense + Sparse |
4단계 | 최종 정렬 | RRF Score | Top 10 | 높은 순 |
RRF (Reciprocal Rank Fusion) 공식:
RRF_score = 1/(k + rank_dense) + 1/(k + rank_sparse)
RRF 장점:
특징 | 설명 | 장점 |
---|---|---|
정규화 불필요 | 점수 범위가 달라도 OK | 단순한 구현 |
상수 k 조정 | 기본 60, 필요시 변경 | 쉬운 튜닝 |
순위 기반 | 점수가 아닌 순위 사용 | 스케일 문제 없음 |
검증된 방법 | Supabase 등에서 사용 | 신뢰성 높음 |
PostgreSQL 18의 성능 개선
벡터 연산 최적화
PostgreSQL 18 + pgvector 0.7.0에서 대폭 성능 향상:
기능 | 개선 내용 | 성능 향상 |
---|---|---|
SIMD 최적화 | 벡터 연산 하드웨어 가속 | 2-3배 ↑ |
병렬 쿼리 | 다중 코어 활용 | 3-5배 ↑ |
HNSW 구축 | 인덱스 생성 속도 개선 | 30% ↑ |
메모리 관리 | 대용량 벡터 처리 안정성 | 안정성 ↑ |
벤치마크 비교
테스트 환경:
- 100K 문서, 1536차원 벡터
- HNSW 인덱스 (m=16, ef_construction=64)
- PostgreSQL 18 vs 15
작업 | PostgreSQL 15 | PostgreSQL 18 | 개선율 |
---|---|---|---|
인덱스 구축 | 180초 | 125초 | 30% ↓ |
단일 벡터 검색 | 15ms | 6ms | 60% ↓ |
배치 검색 (100개) | 1.2초 | 0.4초 | 67% ↓ |
Hybrid Search | 85ms | 32ms | 62% ↓ |
다른 벡터 데이터베이스와 비교
Qdrant vs Milvus vs pgvector
특성 | Qdrant | Milvus | pgvector |
---|---|---|---|
타입 | 전용 벡터 DB | 전용 벡터 DB | PostgreSQL 익스텐션 |
검색 속도 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
확장성 | 수억 개 | 수십억 개 | 수백만 개 |
복잡한 쿼리 | 제한적 | 제한적 | ⭐⭐⭐⭐⭐ (SQL) |
트랜잭션 | ❌ | ❌ | ✅ (ACID) |
운영 복잡도 | 중간 | 높음 | 낮음 |
통합성 | 별도 DB | 별도 DB | PostgreSQL 통합 |
학습 곡선 | 중간 | 높음 | 낮음 (SQL) |
비용 | 중간 | 높음 | 낮음 |
선택 가이드
pgvector를 선택해야 하는 경우:
- ✅ PostgreSQL을 이미 사용 중
- ✅ 벡터 수가 수백만 개 이하
- ✅ 복잡한 JOIN, 집계 쿼리 필요
- ✅ 트랜잭션 보장이 중요
- ✅ 운영 복잡도를 낮추고 싶음
- ✅ Hybrid Search (벡터 + FTS) 구현 필요
Qdrant를 선택해야 하는 경우:
- ✅ 벡터 검색 성능이 최우선
- ✅ 복잡한 필터링 쿼리 (다중 조건)
- ✅ 실시간 업데이트 빈번
- ✅ 클라우드 네이티브 아키텍처
Milvus를 선택해야 하는 경우:
- ✅ 수천만~수억 개 이상의 벡터
- ✅ 엔터프라이즈급 확장성 필요
- ✅ 분산 시스템 경험 보유
- ✅ GPU 가속 활용
실전 활용 예시
RAG (Retrieval Augmented Generation)
테이블 스키마:
컬럼명 | 타입 | 제약조건 | 용도 |
---|---|---|---|
id | UUID | PRIMARY KEY | 문서 고유 ID |
title | TEXT | NOT NULL | 문서 제목 |
content | TEXT | NOT NULL | 문서 내용 |
embedding | vector(3072) | - | OpenAI 임베딩 (large) |
metadata | JSONB | - | 작성자, 태그 등 메타데이터 |
created_at | TIMESTAMP | DEFAULT NOW() | 생성 시간 |
인덱스 구성:
- HNSW 인덱스: embedding 컬럼에 vector_cosine_ops 적용
- GIN 인덱스: metadata JSONB 검색 최적화 (선택)
검색 방식:
검색 유형 | 조건 | 결과 |
---|---|---|
유사도 검색 | ORDER BY embedding <=> query | 가장 유사한 순 |
임계값 필터 | WHERE similarity > 0.7 | 70% 이상만 |
메타데이터 결합 | metadata->>'author' | JSON 필드 추출 |
제한 | LIMIT 5 | 상위 5개 |
의미적 검색 엔진
Hybrid Search 구조:
CTE 단계 | 검색 방식 | 기술 | 결과 수 | 점수 계산 |
---|---|---|---|---|
semantic_results | 의미적 검색 | pgvector 코사인 | Top 20 | 1/(60+rank) |
keyword_results | 키워드 검색 | PostgreSQL FTS | Top 20 | 1/(60+rank) |
최종 결합 | LEFT JOIN | 점수 합산 | Top 10 | semantic + keyword |
검색 특징:
검색 유형 | 강점 | 약점 | 예시 쿼리 |
---|---|---|---|
Semantic | 의미 이해, 유의어 | 정확한 키워드 약함 | ”데이터베이스 성능” |
Keyword | 정확한 매칭 | 의미 이해 불가 | ”PostgreSQL 18” |
Hybrid | 두 장점 결합 | 구현 복잡 | 위 두 개 모두 |
점수 결합 전략:
- RRF (Reciprocal Rank Fusion) 사용
- 0점인 경우 COALESCE로 처리
- 최종 점수로 정렬하여 상위 10개 반환
추천 시스템
콘텐츠 기반 추천 구조:
단계 | SQL 요소 | 역할 | 설명 |
---|---|---|---|
1. 기준 선택 | WHERE d1.id = $1 | 기준 문서 | 사용자가 본 문서 |
2. 비교 대상 | CROSS JOIN | 모든 문서 | 전체 문서와 비교 |
3. 자기 제외 | AND d2.id != $1 | 중복 방지 | 같은 문서 제외 |
4. 유사도 계산 | embedding <=> embedding | 벡터 거리 | 코사인 유사도 |
5. 정렬 | ORDER BY distance | 가장 유사한 순 | 상위 10개 |
추천 알고리즘 유형:
유형 | 방법 | 장점 | 단점 |
---|---|---|---|
Content-based | 벡터 유사도 | 신규 아이템도 추천 가능 | 다양성 부족 |
User-based | 사용자 임베딩 비교 | 개인화 가능 | Cold start 문제 |
Hybrid | Content + User 결합 | 두 장점 활용 | 구현 복잡 |
모범 사례 (Best Practices)
1. 임베딩 정규화
정규화의 중요성:
항목 | 정규화 전 | 정규화 후 | 효과 |
---|---|---|---|
검색 속도 | 기준 | 10-20% 향상 | 연산 최적화 |
코사인 유사도 | 계산 필요 | 내적만으로 계산 가능 | 단순화 |
정확도 | 동일 | 동일 | 변화 없음 |
정규화 방법:
- 벡터를 단위 벡터로 변환 (길이 = 1)
- L2 norm으로 나누기:
vector / ||vector||
- OpenAI 등 대부분 모델은 이미 정규화됨
2. 배치 삽입
삽입 방식별 성능:
방식 | 속도 | 사용 시기 | 특징 |
---|---|---|---|
COPY | 🥇 최고속 | 대량 초기 삽입 | CSV 파일에서 직접 |
준비된 명령문 | 🥈 빠름 | 프로그램에서 삽입 | 반복 실행 최적화 |
단일 INSERT | 🥉 느림 | 소량 데이터 | 간단한 테스트 |
권장 배치 크기:
- 500-2,000개/배치
- PostgreSQL 메모리 한계 고려
- 트랜잭션 단위로 커밋
3. 인덱스 구축 타이밍
대량 삽입 시 전략:
단계 | 작업 | 이유 |
---|---|---|
1단계 | 기존 인덱스 삭제 | 삽입 속도 향상 |
2단계 | 데이터 대량 삽입 | 인덱스 없이 빠르게 |
3단계 | 인덱스 재생성 | 한 번에 구축이 효율적 |
성능 비교:
- 인덱스 유지: 100K 벡터 → 2시간
- 인덱스 재구축: 100K 벡터 → 1시간
4. 메모리 설정 최적화
PostgreSQL 설정 권장값:
설정 | 권장값 | 기준 | 용도 |
---|---|---|---|
shared_buffers | 8GB | RAM의 25% | 공유 메모리 버퍼 |
work_mem | 256MB | 쿼리별 | 정렬/해시 작업 |
maintenance_work_mem | 2GB | 인덱스 구축 | 유지보수 작업 |
effective_cache_size | 24GB | RAM의 75% | OS 캐시 추정 |
5. 모니터링
주요 모니터링 지표:
지표 | 확인 방법 | 정상 범위 | 조치 |
---|---|---|---|
인덱스 크기 | pg_relation_size() | 벡터 크기의 3-5배 | 파라미터 조정 |
쿼리 시간 | EXPLAIN ANALYZE | < 50ms (100K 벡터) | 인덱스 최적화 |
캐시 히트율 | pg_stat_database | > 95% | shared_buffers 증가 |
인덱스 스캔 비율 | pg_stat_user_indexes | > 80% | 인덱스 효율성 확인 |
제한사항 및 고려사항
제한사항
항목 | 제한 | 설명 |
---|---|---|
최대 차원 | 16,000 | 일반적으로 충분 (대부분 모델 < 5,000) |
인덱스 타입 | HNSW, IVFFlat | 다른 알고리즘 미지원 |
동적 업데이트 | 인덱스 재구축 | HNSW는 추가 최적화되지 않음 |
권장 벡터 수 | < 수백만 | 이상은 전용 벡터 DB 고려 |
성능 고려사항
인덱스 vs 순차 스캔:
- 벡터 수 < 1,000: 인덱스 불필요 (순차 스캔이 더 빠름)
- 벡터 수 1K-10K: IVFFlat 고려
- 벡터 수 > 10K: HNSW 권장
메모리 사용:
- HNSW 인덱스: 약 벡터 크기의 3-5배
- 예: 100K 벡터 × 1536차원 × 4바이트 × 4배 ≈ 2.4GB
참고 자료
공식 문서
- pgvector GitHub: 공식 저장소
- Supabase Hybrid Search Guide: RRF 구현 가이드
- PostgreSQL Documentation: PostgreSQL 18 공식 문서
관련 기술
- RAG+Groq: RAG 시스템 구축
- LangChain: 문서 처리 파이프라인
- Knowledge Graphs for RAG: 지식 그래프 연동
- pgvector 활용 벡터베이스 구현: 실전 프로젝트 예시
핵심 개념
- ANN (Approximate Nearest Neighbor): 근사 최근접 이웃 검색
- HNSW (Hierarchical Navigable Small World): 그래프 기반 ANN 알고리즘
- RRF (Reciprocal Rank Fusion): Hybrid Search 결과 결합 방식
- Embedding: 텍스트/이미지를 고차원 벡터로 표현
- Cosine Similarity: 벡터 간 방향 유사도 측정
결론
pgvector는 PostgreSQL에서 벡터 검색을 가능하게 하는 강력하고 실용적인 익스텐션이다. 전용 벡터 데이터베이스 대비 성능은 약간 떨어질 수 있지만, PostgreSQL의 모든 기능을 활용할 수 있다는 점과 운영 복잡도가 낮다는 점이 큰 장점이다.
핵심 포인트:
- ✅ PostgreSQL 통합으로 단일 DB 운영
- ✅ SQL로 벡터 + 관계형 데이터 동시 쿼리
- ✅ HNSW 인덱스로 빠른 ANN 검색
- ✅ FTS와 결합한 Hybrid Search 구현 용이
- ✅ PostgreSQL 18에서 대폭 성능 개선
언제 사용할까?
- PostgreSQL을 이미 사용 중이거나
- 수백만 개 이하의 벡터를 다루거나
- 복잡한 SQL 쿼리가 필요하거나
- 운영 복잡도를 낮추고 싶다면
pgvector는 RAG, 의미적 검색, 추천 시스템 등 다양한 AI 애플리케이션의 백본으로 활용할 수 있는 훌륭한 선택지다.