
pgvector는 Postgres 안에서 embedding vector를 저장하고 유사도 검색을 할 수 있게 해주는 확장입니다. RAG를 처음 붙일 때는 별도 벡터 DB를 운영하기 전에 pgvector로 시작할 수 있는지 검토할 만합니다.
하지만 핵심은 pgvector가 더 좋다거나 전용 벡터 DB가 항상 과하다는 결론이 아니라, 데이터 규모와 운영 책임을 비교하는 것입니다. 이미 Postgres가 있는 서비스와 처음부터 대규모 검색을 노리는 서비스의 답은 다를 수 있습니다.

pgvector는 무엇을 해주는가
pgvector는 Postgres에 vector 타입과 유사도 검색 기능을 더합니다. 문서 chunk, embedding, metadata를 같은 데이터베이스 안에 넣고 SQL로 조회할 수 있다는 점이 가장 큰 장점입니다.
CREATE EXTENSION vector;
CREATE TABLE documents (
id bigserial PRIMARY KEY,
title text,
body text,
embedding vector(1536)
);Postgres 안에서 시작하는 장점
- 기존 백업, 권한, 모니터링 체계를 재사용하기 쉽다
- 문서 metadata와 업무 데이터를 SQL로 함께 다루기 쉽다
- 작은 RAG 기능을 위해 별도 인프라를 늘리지 않아도 된다
- 트랜잭션과 migration 흐름을 기존 서비스와 맞추기 쉽다
특히 관리자용 검색, 내부 지식베이스, 작은 제품 기능처럼 규모가 크지 않은 RAG라면 pgvector로 시작하는 것이 단순할 수 있습니다.
전용 벡터 DB가 필요한 신호
검색량이 빠르게 늘거나, index 운영, 분산 처리, 고급 filtering, multi-tenant 격리, 운영 UI가 중요해지면 Qdrant나 Pinecone 같은 전용 벡터 DB를 검토할 수 있습니다.
- embedding 수가 빠르게 늘고 latency 목표가 빡빡하다
- 검색 전용 scaling과 운영 기능이 필요하다
- metadata filter와 vector search 조합이 복잡하다
- 서비스 DB와 검색 DB의 장애 범위를 분리하고 싶다
ANN index를 이해해야 한다
벡터 검색은 모든 벡터를 매번 비교하면 비용이 커집니다. 그래서 approximate nearest neighbor index를 사용해 빠르게 가까운 후보를 찾습니다. pgvector도 index를 지원하지만, index 종류와 파라미터에 따라 정확도와 속도 tradeoff가 생깁니다.
CREATE INDEX ON documents
USING hnsw (embedding vector_cosine_ops);metadata filter는 RAG 품질에 중요하다
RAG 검색은 단순히 의미적으로 가까운 문서만 찾는 문제가 아닙니다. 문서 권한, 언어, 날짜, 제품 버전, 카테고리 같은 filter가 답변 품질과 보안에 직접 영향을 줍니다.
pgvector를 쓰면 SQL where 조건과 vector search를 한 쿼리 흐름에서 다룰 수 있습니다. 전용 벡터 DB도 metadata filter를 제공하지만, 기존 업무 데이터와의 join 방식은 별도로 설계해야 합니다.
선택 기준
- 이미 Postgres 운영 체계가 있고 규모가 작으면 pgvector로 시작한다
- 검색량과 embedding 수가 빠르게 커지면 전용 벡터 DB를 검토한다
- metadata filter가 업무 DB와 강하게 엮이면 pgvector가 단순할 수 있다
- 분산 운영과 검색 전용 기능이 중요하면 Qdrant/Pinecone 후보를 본다
- 초기에는 평가셋으로 검색 품질과 latency를 함께 측정한다
정리
pgvector는 RAG를 Postgres 안에서 작게 시작하게 해주는 좋은 선택지입니다. 하지만 검색 규모와 운영 요구가 커질수록 전용 벡터 DB의 장점도 분명해집니다.
pgvector 기본 기능은 pgvector 공식 저장소를 기준으로 확인할 수 있습니다. RAG chunking 기준은 한국어 RAG chunk size 글과 함께 보면 좋습니다.
보강: pgvector로 시작해도 되는 서비스 크기
pgvector는 작은 RAG 기능을 빠르게 시작하기 좋습니다. 예를 들어 내부 문서 수가 수천~수십만 chunk 수준이고, 검색 QPS가 높지 않으며, 이미 Postgres 백업과 모니터링이 잡혀 있다면 별도 벡터 DB를 도입하기 전 충분히 검토할 만합니다.
반대로 embedding 수가 수백만~수천만 단위로 빠르게 늘거나, 검색 latency가 제품 핵심 지표라면 처음부터 전용 벡터 DB PoC를 병행하는 편이 낫습니다. pgvector가 부족해서라기보다 Postgres가 맡아야 할 업무가 너무 많아질 수 있기 때문입니다.
스키마를 어떻게 나누면 좋을까
문서 원문, chunk, embedding을 한 테이블에 모두 넣을 수도 있지만 운영이 커질수록 역할을 나누는 편이 좋습니다. 원문 문서와 검색 단위 chunk는 생명주기가 다를 수 있습니다.
CREATE TABLE documents (
id bigserial PRIMARY KEY,
source text NOT NULL,
title text NOT NULL,
updated_at timestamptz NOT NULL
);
CREATE TABLE document_chunks (
id bigserial PRIMARY KEY,
document_id bigint REFERENCES documents(id),
chunk_index int NOT NULL,
content text NOT NULL,
embedding vector(1536),
metadata jsonb NOT NULL DEFAULT '{}'
);이렇게 나누면 원문 metadata를 관리하면서 chunk 재생성, embedding 재계산, 오래된 chunk 삭제를 더 명확히 처리할 수 있습니다.
metadata filter를 먼저 설계해야 하는 이유
RAG 검색에서 권한과 범위는 품질 문제이면서 보안 문제입니다. 사용자가 볼 수 없는 문서가 검색 후보에 들어오면 LLM이 직접 보여주지 않더라도 위험한 구조가 됩니다.
- tenant_id: 조직별 문서 격리
- visibility: public, internal, private 구분
- document_type: guide, faq, ticket, policy 구분
- version: 제품 버전별 문서 필터
- language: 한국어/영어 문서 혼합 검색 제어
검색 쿼리 흐름 예시
SELECT
id,
content,
metadata,
embedding <=> $1 AS distance
FROM document_chunks
WHERE metadata->>'tenant_id' = $2
AND metadata->>'language' = 'ko'
ORDER BY embedding <=> $1
LIMIT 8;이 예시는 단순하지만 중요한 기준을 보여줍니다. vector distance만 보지 않고, tenant와 language 같은 업무 조건을 먼저 걸어야 합니다.
전용 벡터 DB로 옮길 때 생기는 비용
전용 벡터 DB로 가면 검색 기능은 강해질 수 있지만 데이터 동기화 책임이 생깁니다. 원본 DB와 벡터 DB 사이에 chunk 생성, embedding 생성, 삭제 반영, 권한 변경 반영 흐름이 필요합니다.
- 원본 문서 변경 이벤트를 잡는다
- chunk를 다시 만든다
- embedding을 다시 생성한다
- vector DB에 upsert한다
- 삭제/권한 변경 이벤트도 누락 없이 반영한다
PoC에서 반드시 측정할 것
- top-k 안에 정답 근거가 들어오는 비율
- metadata filter 적용 후 latency
- chunk 수가 늘어날 때 index 생성 시간
- embedding 재계산 배치 시간
- Postgres 본래 트랜잭션 업무에 주는 부하