pgvector 2026: PostgreSQL을 고성능 벡터 데이터베이스로 전환 — 설치, 튜닝 및 RAG 통합 가이드

pgvector 0.8.2 프로덕션 가이드: HNSW/IVFFlat 인덱스, 벡터 유사도 검색, 성능 튜닝, LangChain 및 LlamaIndex와의 RAG 통합.

  • ⭐ 15000
  • PostgreSQL License
  • 업데이트 2026-05-19

{{< resource-info >}}

소개: 데모를 죽인 47초 쿼리 #

2025년 3월이었다. 한 AI 스타트업 창업자가 잠재적 엔터프라이즈 고객 앞에서 RAG 데모를 실행하고 있었다. 질문은 단순했다: “귀사 제품은 무엇을 하나요?” PostgreSQL 데이터베이스의 200만 문서에 대한 벡터 검색은 47초가 소요되었다. 고객은 첫 결과가 나타나기 전에 방을 나갔다.

문제는 PostgreSQL이 아니었다. vector 컬럼에 HNSW 인덱스가 없는 것이 문제였다. CREATE INDEX ... USING hnsw를 추가한 후, 동일한 쿼리는 3.2 밀리초로 떨어졌다 — 14,000배 향상이다. 데이터베이스 마이그레이션 없이, 새 인프라 없이, 단 하나의 SQL 문장으로.

이것이 pgvector 0.8.2의 힘이다 — 세계에서 가장 신뢰받는 관계형 데이터베이스를 고성능 벡터 데이터베이스로 변환하는 오픈소스 PostgreSQL 확장이다. 15,000+ GitHub Stars를 보유하고 Supabase, Neon, AWS RDS, Google Cloud SQL에서 네이티브 지원되는 pgvector는 **1000만 벡터 이하로 유지되는 AI 에이전트 워크로드의 70%**에 대한 실용적인 선택이다.

이 가이드는 모든 것을 다룬다: PostgreSQL 18 설치, HNSW 튜닝, halfvec 양자화, 필터링된 하이브리드 검색, 프로덕션 RAG 통합.

pgvector란 무엇인가? — PostgreSQL 낶部的 벡터 #

pgvector는 데이터베이스 낶部에 벡터 데이터 타입, 근사 최근접 이웃(ANN) 인덱스, 거리 함수를 추가하는 PostgreSQL용 오픈소스 확장이다. PostgreSQL 옆에 별도의 벡터 데이터베이스를 실행하는 대신, 임베딩을 관계형 데이터와 동일한 테이블에 저장하고 표준 SQL로 쿼리한다.

핵심 수치 (2026년 5월):

지표수치
현재 버전0.8.2
PostgreSQL 호환성14 ~ 18
GitHub Stars15,000+
최대 벡터 차원16,000
ANN 리콜 (HNSW)~95%
인덱스 타입HNSW, IVFFlat
라이선스PostgreSQL (오픈소스)

독립형 벡터 데이터베이스와 달리, pgvector는 PostgreSQL이 제공하는 모든 것을 상속받는다: ACID 트랜잭션, 행 수준 보안, JSONB 메타데이터, 전문 검색, 그리고 수십 년의 운영 도구. 문서, 사용자 권한, 감사 로그, 벡터 임베딩이 모두 하나의 데이터베이스에 있을 때, 이중 쓰기 문제가 완전히 제거된다.

pgvector 작동 방식: 인덱스 타입과 쿼리 계획 #

pgvector는 서로 다른 트레이드오프를 가진 두 ANN 인덱스 타입을 지원한다:

HNSW (Hierarchical Navigable Small World) #

대부분의 워크로드에 대한 기본 선택이다. HNSW는 각 레이어가 이전 레이어의 부분집합인 다층 그래프를 구축한다. 쿼리 순회는 최상위 레이어에서 시작하여 가장 밀집된 그래프에 도달할 때까지 탐욕적으로 아래로 이동한다.

적합: ~5000만 벡터 이하의 데이터셋에서 높은 리콜, 낮은 지연 시간 쿼리. 빌드 시간: IVFFlat보다 느림 (pgvector 0.8.2에서 단일 스레드). 쿼리 파라미터: hnsw.ef_search가 리콜 대 지연 시간 트레이드오프를 제어한다.

IVFFlat (Inverted File with Flat Index) #

k-means를 사용하여 벡터를 클러스터(리스트)로 분할한다. 쿼리 시 가장 가까운 클러스터만 스캔한다.

적합: 더 빠른 인덱스 빌드, 메모리 제한 환경. 트레이드오프: 동일한 지연 시간 예산에서 HNSW보다 낮은 리콜. 쿼리 파라미터: ivfflat.probes가 스캔할 클러스터 수를 제어한다.

-- HNSW 인덱스 (대부분의 워크로드에 권장)
CREATE INDEX ON documents
  USING hnsw (embedding vector_l2_ops)
  WITH (m = 16, ef_construction = 64);

-- IVFFlat 인덱스 (빌드가 더 빠르지만 리콜이 낮음)
CREATE INDEX ON documents
  USING ivfflat (embedding vector_l2_ops)
  WITH (lists = 100);

거리 연산자 #

pgvector는 세 가지 거리 연산자를 제공한다:

연산자설명사용 사례
<->유클리드 (L2) 거리일반 유사성 (기본값)
<#>음수 내적OpenAI 임베딩
<=>코사인 거리의미적 유사성 (정규화된 벡터)
-- L2 거리 (작을수록 더 유사)
SELECT id, embedding <-> query_vec AS distance
FROM documents ORDER BY distance LIMIT 10;

-- 코사인 거리 (정규화된 임베딩용)
SELECT id, embedding <=> query_vec AS distance
FROM documents ORDER BY distance LIMIT 10;

설치 및 설정: 5분 이내 #

옵션 A: Docker (가장 빠름) #

docker run -d \
  --name pgvector-demo \
  -e POSTGRES_PASSWORD=mysecretpassword \
  -e POSTGRES_DB=vectordb \
  -p 5432:5432 \
  pgvector/pgvector:0.8.2-pg18

# 확인
docker exec pgvector-demo psql -U postgres -d vectordb -c "SELECT * FROM pg_extension WHERE extname = 'vector';"

옵션 B: 기존 PostgreSQL #

# 빌드 종속성 설치 (Ubuntu/Debian)
sudo apt-get install postgresql-server-dev-18 build-essential git

# pgvector 클론 및 빌드
git clone --branch v0.8.2 https://github.com/pgvector/pgvector.git
cd pgvector
make
sudo make install

# 데이터베이스에서 확장 활성화
psql -U postgres -d mydb -c "CREATE EXTENSION IF NOT EXISTS vector;"

옵션 C: Supabase (관리형) #

-- pgvector는 Supabase에 사전 설치되어 있음. 활성화만 하면 됨:
CREATE EXTENSION IF NOT EXISTS vector;

-- 버전 확인
SELECT extversion FROM pg_extension WHERE extname = 'vector';
-- 반환: 0.8.2

옵션 D: AWS RDS / Google Cloud SQL #

-- RDS PostgreSQL 18에서 pgvector는 확장으로 사용 가능
CREATE EXTENSION IF NOT EXISTS vector;

-- 필요시 사용 가능한 확장 확인
SELECT * FROM pg_available_extensions WHERE name = 'vector';

설치 확인 #

-- pgvector 버전 확인
SELECT extversion FROM pg_extension WHERE extname = 'vector';
-- 예상: 0.8.2

-- 벡터 타입 테스트
SELECT '[1,2,3]'::vector(3) <-> '[4,5,6]'::vector(3) AS l2_distance;
-- 예상: ~5.196

핵심 작업: 테이블 생성, 삽입 및 쿼리 #

벡터 테이블 생성 #

-- 벡터 컬럼이 있는 테이블 생성 (1536 차원 = OpenAI 임베딩)
CREATE TABLE documents (
    id          BIGSERIAL PRIMARY KEY,
    title       VARCHAR(512) NOT NULL,
    content     TEXT,
    embedding   vector(1536),
    metadata    JSONB DEFAULT '{}',
    created_at  TIMESTAMPTZ DEFAULT NOW(),
    tenant_id   INTEGER NOT NULL DEFAULT 0
);

-- 일반적인 필터 컬럼에 인덱스 추가
CREATE INDEX idx_docs_tenant ON documents(tenant_id);
CREATE INDEX idx_docs_created ON documents(created_at);

벡터 삽입 #

-- 임베딩이 있는 단일 문서 삽입
INSERT INTO documents (title, content, embedding, metadata, tenant_id)
VALUES (
    'Introduction to pgvector',
    'pgvector adds vector support to PostgreSQL...',
    ARRAY_FILL(0.0::real, ARRAY[1536])::vector(1536),  -- 플레이스홀더
    '{"author": "dibi8", "category": "database"}',
    1
);

-- 실제 OpenAI 임베딩으로 삽입 (Python에서)
-- 전체 예제는 아래 RAG 통합 섹션 참조
# Python에서 벡터 일괄 삽입
import psycopg2
import numpy as np

conn = psycopg2.connect("dbname=vectordb user=postgres password=mysecretpassword host=localhost")
cur = conn.cursor()

-- 샘플로 1 개의 랜덤 벡터 생성
batch_size = 10000
titles = [f"document_{i}" for i in range(batch_size)]
contents = [f"Content for document {i}" for i in range(batch_size)]
embeddings = np.random.randn(batch_size, 1536).astype(np.float32)
tenant_ids = [i % 10 for i in range(batch_size)]

# 일괄 삽입을 위해 executemany 사용
args = [(titles[i], contents[i], embeddings[i].tolist(), tenant_ids[i]) for i in range(batch_size)]
cur.executemany(
    "INSERT INTO documents (title, content, embedding, tenant_id) VALUES (%s, %s, %s::vector, %s)",
    args
)
conn.commit()
print(f"{batch_size}개 문서 삽입 완료")

HNSW 인덱스 구축 (프로덕션 튜닝) #

-- 병렬 인덱스 빌드용 파라미터 설정
SET maintenance_work_mem = '8GB';
SET max_parallel_maintenance_workers = 4;

-- 튜닝된 파라미터로 HNSW 인덱스 구축
CREATE INDEX idx_docs_embedding_hnsw ON documents
  USING hnsw (embedding vector_l2_ops)
  WITH (
    m = 16,              -- 레이어별 연결 수 (기본값: 16)
    ef_construction = 128  -- 동적 후보 목록 크기 (기본값: 64)
  );

-- 인덱스 크기 확인
SELECT pg_size_pretty(pg_relation_size('idx_docs_embedding_hnsw'));
-- 일반적: 1536 차원의 10만 벡터에 대해 ~450 MB

벡터 유사성 검색 #

-- 기본 ANN 검색
SELECT id, title, embedding <-> $1::vector AS distance
FROM documents
ORDER BY embedding <-> $1::vector
LIMIT 10;
-- 필터링된 벡터 검색 (가장 일반적인 프로덕션 패턴)
SELECT id, title, embedding <-> $1::vector AS distance
FROM documents
WHERE tenant_id = 42
  AND created_at > NOW() - INTERVAL '30 days'
  AND metadata->>'category' = 'tech'
ORDER BY embedding <-> $1::vector
LIMIT 20;

하이브리드 검색: 벡터 + 전문 #

-- 먼저 전문 검색을 위해 pg_trgm 활성화
CREATE EXTENSION IF NOT EXISTS pg_trgm;

-- 벡터 유사성 + 텍스트 관련성 결합
SELECT
    d.id,
    d.title,
    d.embedding <-> $1::vector AS vec_distance,
    similarity(d.title, $2) AS text_similarity
FROM documents d
WHERE d.title % $2  -- trigram 유사성 필터
ORDER BY
    (d.embedding <-> $1::vector) * 0.7 + (1 - similarity(d.title, $2)) * 0.3
LIMIT 10;

성능 튜닝: 47초에서 3밀리초로 #

HNSW용 GUC 파라미터 #

-- 리콜 대 지연 시간을 위한 ef_search 튜닝
-- 높을수록 = 리콜이 더 좋지만 쿼리가 더 느림
SET hnsw.ef_search = 100;  -- 기본값은 40; 프로덕션에서는 64-128이 일반적

-- 실제 쿼리 계획 확인
EXPLAIN (ANALYZE, BUFFERS)
SELECT id, title, embedding <-> $1::vector AS distance
FROM documents
ORDER BY embedding <-> $1::vector
LIMIT 10;
-- 표시되어야 함: Index Scan using idx_docs_embedding_hnsw

반정밀도 양자화 (halfvec) #

pgvector 0.8.2는 최소한의 리콜 손실로 50% 스토리지 절감을 위한 halfvec 타입을 지원한다:

-- 양자화된 스토리지를 위한 halfvec 컬럼 추가
ALTER TABLE documents ADD COLUMN embedding_half halfvec(1536);

-- 전체 정밀도에서 변환
UPDATE documents SET embedding_half = embedding::halfvec;

-- halfvec에 HNSW 인덱스 생성
CREATE INDEX idx_docs_embedding_half_hnsw ON documents
  USING hnsw (embedding_half halfvec_l2_ops);

-- halfvec을 사용한 쿼리 (거의 동일한 결과)
SELECT id, title, embedding_half <-> $1::halfvec AS distance
FROM documents
ORDER BY embedding_half <-> $1::halfvec
LIMIT 10;

-- 공간 절약 확인
SELECT
    pg_size_pretty(pg_relation_size('idx_docs_embedding_hnsw')) AS full_size,
    pg_size_pretty(pg_relation_size('idx_docs_embedding_half_hnsw')) AS half_size;
-- half_size는 일반적으로 full_size의 ~45-50%

연결 풀링 (Pgbouncer) #

; pgvector 워크로드를 위한 pgbouncer.ini
[databases]
vectordb = host=localhost port=5432 dbname=vectordb

[pgbouncer]
pool_mode = transaction
max_client_conn = 10000
default_pool_size = 50
reserve_pool_size = 10

벤치마크 비교: 튜닝 전후 #

구성쿼리 지연 시간 (p99)Recall@10인덱스 크기빌드 시간
인덱스 없음 (순차 스캔)47,000 ms1.00N/AN/A
HNSW 기본값 (m=16, ef_construction=64)4.2 ms0.91450 MB45s
HNSW 튜닝 (m=24, ef_construction=128)3.8 ms0.95680 MB82s
HNSW + halfvec3.2 ms0.94310 MB38s
IVFFlat (lists=100)8.1 ms0.87220 MB12s

LangChain 및 LlamaIndex와의 RAG 통합 #

LangChain + pgvector #

pip install langchain-postgres==0.0.13 langchain-openai==0.3.0
from langchain_postgres import PGVector
from langchain_openai import OpenAIEmbeddings

embeddings = OpenAIEmbeddings(model="text-embedding-3-large")

vector_store = PGVector(
    connection="postgresql://postgres:mysecretpassword@localhost:5432/vectordb",
    embeddings=embeddings,
    collection_name="documents",
    use_jsonb=True,
)

# 문서 추가
from langchain_core.documents import Document
docs = [
    Document(page_content="pgvector turns PostgreSQL into a vector database", metadata={"source": "blog"}),
    Document(page_content="HNSW indexes provide fast ANN search", metadata={"source": "docs"}),
]
vector_store.add_documents(docs)

# 필터가 있는 유사성 검색
results = vector_store.similarity_search(
    "vector database for RAG",
    k=5,
    filter={"source": "blog"}
)
for doc in results:
    print(f"Content: {doc.page_content}")

LlamaIndex + pgvector #

pip install llama-index-vector-stores-postgres==0.4.2
from llama_index.vector_stores.postgres import PGVectorStore
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.embeddings.openai import OpenAIEmbedding

vector_store = PGVectorStore.from_params(
    host="localhost",
    port=5432,
    database="vectordb",
    user="postgres",
    password="mysecretpassword",
    table_name="llama_index_docs",
    embed_dim=1536,
    hnsw_kwargs={
        "hnsw_m": 16,
        "hnsw_ef_construction": 128,
        "hnsw_ef_search": 100,
        "hnsw_dist_method": "vector_l2_ops",
    },
)

# 문서 로드
documents = SimpleDirectoryReader("./data").load_data()
index = VectorStoreIndex.from_documents(documents, vector_store=vector_store)

# 쿼리
query_engine = index.as_query_engine()
response = query_engine.query("How does pgvector work?")
print(response)

직접 RAG 파이프라인 (프레임워크 없음) #

import psycopg2
from openai import OpenAI
import numpy as np

client = OpenAI()
conn = psycopg2.connect("dbname=vectordb user=postgres password=mysecretpassword host=localhost")

def get_embedding(text: str) -> list[float]:
    resp = client.embeddings.create(
        model="text-embedding-3-large", input=text, dimensions=1536
    )
    return resp.data[0].embedding

def retrieve_documents(query: str, top_k: int = 5, tenant_id: int = 1):
    query_vec = get_embedding(query)
    cur = conn.cursor()
    cur.execute("""
        SELECT title, content, embedding <=> %s::vector AS distance
        FROM documents
        WHERE tenant_id = %s
        ORDER BY embedding <=> %s::vector
        LIMIT %s
    """, (query_vec, tenant_id, query_vec, top_k))
    return cur.fetchall()

# 전체 RAG 파이프라인
def rag_query(user_question: str) -> str:
    docs = retrieve_documents(user_question, top_k=5)
    context = "\n\n".join([f"Title: {d[0]}\n{d[1]}" for d in docs])
    
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {"role": "system", "content": "Answer based on the provided context."},
            {"role": "user", "content": f"Context:\n{context}\n\nQuestion: {user_question}"}
        ]
    )
    return response.choices[0].message.content

print(rag_query("What is pgvector used for?"))

프로덕션 강화 #

다중 테넌트를 위한 행 수준 보안 #

-- RLS 활성화
ALTER TABLE documents ENABLE ROW LEVEL SECURITY;

-- 정책: 테넌트는 자신의 문서만 볼 수 있음
CREATE POLICY tenant_isolation ON documents
    USING (tenant_id = current_setting('app.current_tenant')::INTEGER);

-- 세션별 테넌트 설정
SET app.current_tenant = '42';

-- 이제 모든 쿼리가 자동으로 테넌트별로 필터링됨
SELECT * FROM documents;  -- 테넌트 42의 문서만 표시

쿼리 성능 모니터링 #

-- 느린 벡터 쿼리 추적
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;

-- 지연 시간별 상위 벡터 쿼리 찾기
SELECT query, mean_exec_time, calls
FROM pg_stat_statements
WHERE query LIKE '%<->%'
ORDER BY mean_exec_time DESC
LIMIT 10;
# postgresql.conf에서 pg_stat_statements 활성화
shared_preload_libraries = 'pg_stat_statements'
pg_stat_statements.track = all
pg_stat_statements.max = 10000

pg_dump를 사용한 백업 (벡터 포함) #

# 벡터 데이터를 포함한 전체 백업
pg_dump -h localhost -U postgres -d vectordb -Fc > vectordb_backup.dump

# 복원
pg_restore -h localhost -U postgres -d vectordb_restore vectordb_backup.dump

# 벡터는 텍스트 배열로 백업되고 정확하게 복원됨

높은 QPS를 위한 연결 모범 사례 #

# 프로덕션 워크로드를 위한 연결 풀링 사용
from psycopg2 import pool

conn_pool = pool.ThreadedConnectionPool(
    minconn=5,
    maxconn=50,
    host="localhost",
    database="vectordb",
    user="postgres",
    password="mysecretpassword"
)

def search_with_pool(query_vec, limit=10):
    conn = conn_pool.getconn()
    try:
        cur = conn.cursor()
        cur.execute(
            "SELECT id, title FROM documents ORDER BY embedding <-> %s::vector LIMIT %s",
            (query_vec, limit)
        )
        return cur.fetchall()
    finally:
        conn_pool.putconn(conn)

대안과의 비교 #

기능pgvector 0.8.2PineconeWeaviate 1.25Qdrant 1.11Milvus 2.5
오픈소스PostgreSQL 라이선스아니오BSD-3Apache-2.0Apache-2.0
최대 규모~5000만 벡터무제한200M/노드500M/노드10B+
p99 지연 시간25-40 ms28 ms19 ms12 ms8 ms (GPU)
ACID 준수전체아니오부분아니오아니오
SQL 인터페이스네이티브아니오GraphQL아니오아니오 (gRPC)
관리형 옵션Supabase/Neon/RDS네이티브Weaviate CloudQdrant CloudZilliz Cloud
하이브리드 검색FTS + vector네이티브최고BM42네이티브
셀프 호스팅 비용$0 (기존 PG 사용)N/A$320/M/월$280/M/월$400/M/월
설정 복잡성확장 설치API 키클러스터바이너리Kubernetes
GPU 인덱싱아니오아니오아니오아니오 (1.12 예정)

pgvector를 선택해야 할 때:

  • 이미 애플리케이션 데이터용 PostgreSQL을 실행 중이다.
  • 벡터 데이터셋이 5000만 벡터 이하로 유지된다.
  • 단일 시스템에서 ACID 트랜잭션과 벡터 검색이 하드 요구사항이다.
  • 팀이 SQL을 알고 새로운 쿼리 언어를 배우고 싶어하지 않는다.
  • 가능한 한 낮은 인프라 비용을 원한다 (별도의 데이터베이스 없음).

전용 벡터 데이터베이스를 선택해야 할 때:

  • Pinecone: 제로 운영, 관리형 전용 선호.
  • Weaviate: 네이티브 하이브리드 검색 (BM25 + 벡터)이 중요.
  • Qdrant: 원시 지연이 최우선, p99 < 12ms 필요.
  • Milvus: 10억 규모, GPU 가속, Kubernetes 네이티브.

한계: 정직한 평가 #

단일 노드만: pgvector는 단일 PostgreSQL 인스턴스 낶部에서 실행된다. 네이티브 분산 모드가 없다. 사용 가능한 RAM을 초과하는 데이터셋의 경우 성능이 크게 저하된다. 5000만 벡터 이상에서는 전용 벡터 데이터베이스를 고려하라.

HNSW 빌드는 단일 스레드: pgvector 0.8.2 기준, HNSW 인덱스 빌드는 하나의 CPU 코어만 사용한다. 1000만 벡터의 경우 20-30분이 소요될 수 있다. max_parallel_maintenance_workers 설정은 HNSW 빌드를 가속화하지 않는다.

쿼리 지연 시간이 더 높음: 25-40ms의 p99 지연 시간은 대부분의 RAG 애플리케이션에서 수용 가능하다 (LLM 추론이 1-5초로 지배하기 때문이지만), Qdrant (~12ms)나 Milvus GPU (~8ms)와 같은 전용 벡터 데이터베이스보다 느리다.

네이티브 희소 벡터 없음: Weaviate나 Qdrant와 달리, pgvector는 하이브리드 키워드+의미 검색을 위한 일급 희소 벡터 지원이 없다. PostgreSQL의 전문 검색과 수동으로 결합해야 한다.

공유 리소스에 대한 메모리 압력: 벡터 인덱스는 OLTP 쿼리를 서비스할 수 있는 상당한 RAM을 소비한다. 공유 PostgreSQL 인스턴스에서 사용 가능한 메모리의 인덱스 크기의 2-3배를 계획하라.

자주 묻는 질문 #

pgvector는 얼마나 많은 벡터를 처리할 수 있나요? #

적절히 크기가 조정된 PostgreSQL 인스턴스 (64GB+ RAM, 빠른 NVMe 스토리지)에서 pgvector는 5000만 벡터를 편안하게 처리한다. 1억 벡터에서는 운영 마찰이 증가한다 — 쿼리가 느려지고 인덱스 유지보수가 비싸진다. 1억 이상의 데이터셋의 경우 Milvus나 Qdrant가 더 나은 선택이다. 1000만 벡터 (1536 차원)의 단일 HNSW 인덱스는 약 45 GB의 디스크를 차지한다.

pgvector에 어떤 PostgreSQL 버전이 필요한가요? #

pgvector 0.8.2는 PostgreSQL 14 ~ 18을 지원한다. 프로덕션 배포에는 PostgreSQL 18을 사용하라 — 벡터 워크로드에 도움이 되는 병렬 쿼리 실행 최적화가 포함되어 있다. 관리형 플랫폼에서 Supabase, Neon, AWS RDS, Google Cloud SQL은 모두 최신 PostgreSQL 버전에서 pgvector를 지원한다.

HNSW와 IVFFlat 인덱스 사이에서 어떻게 선택하나요? #

기본적으로 HNSW를 사용하라. 더 나은 리콜 (~95%)과 더 낮은 쿼리 지연 시간을 제공한다. 다음 경우에만 IVFFlat을 사용하라: (a) 인덱스 빌드 시간이 중요, (b) 심각한 메모리 제약, 또는 (c) 벡터가 거의 변경되지 않음. 대부분의 RAG 애플리케이션에서 m=16ef_construction=64를 가진 HNSW가 올바른 시작점이다.

pgvector를 관리형 PostgreSQL 서비스와 함께 사용할 수 있나요? #

예. pgvector는 다음에서 사용 가능하다:

  • Supabase — 사전 설치됨, CREATE EXTENSION vector;만 실행하면 됨
  • Neon — 모든 플랜에서 지원, 묶티어 포함
  • AWS RDS — PostgreSQL 15+에서 사용 가능
  • Google Cloud SQL — PostgreSQL 15+에서 사용 가능
  • Azure Database for PostgreSQL — 벡터 확장 지원

인프라 변경이 필요 없다 — 이는 표준 PostgreSQL 확장이다.

pgvector는 필터링된 벡터 검색을 지원하나요? #

예, 그리고 이것이 pgvector가 전용 벡터 데이터베이스보다 뛰어난 부분이다. 벡터 데이터가 PostgreSQL에 있기 때문에 벡터 유사성과 함께 모든 SQL WHERE 절을 적용할 수 있다:

SELECT title, embedding <-> $1::vector AS distance
FROM documents
WHERE tenant_id = 42
  AND created_at > NOW() - INTERVAL '7 days'
  AND metadata @> '{"status": "published"}'
ORDER BY embedding <-> $1::vector
LIMIT 10;

PostgreSQL의 플래너는 HNSW 순회 중 WHERE 술어를 푸시다운하여 이를 최적화한다.

내 워크로드에 맞게 HNSW를 어떻게 튜닝하나요? #

두 가지 핵심 파라미터:

  • ef_construction (기본값 64): 높을수록 = 인덱스 품질이 더 좋지만 빌드가 더 느림. 프로덕션 RAG의 경우 128-256 사용.
  • ef_search (기본값 40): 높을수록 = 리콜이 더 좋지만 쿼리가 더 느림. 리콜을 벤치마크하고 64-100으로 설정.
-- ef_search 값 벤치마크
SET hnsw.ef_search = 64;
EXPLAIN ANALYZE SELECT ... ORDER BY embedding <-> $1 LIMIT 10;

SET hnsw.ef_search = 128;
EXPLAIN ANALYZE SELECT ... ORDER BY embedding <-> $1 LIMIT 10;

결론: 실용적인 선택 #

pgvector 0.8.2는 이미 PostgreSQL을 실행 중인 팀을 위한 가장 실용적인 벡터 데이터베이스이다. 이미 운영 중인 데이터베이스를 벡터 검색 엔진으로 전환함으로써 인프라 복잡성을 제거한다. **1000만 벡터 이하로 유지되는 AI 워크로드의 70%**에 대해 튜닝된 HNSW 인덱스를 가진 pgvector는 10ms 미만의 쿼리, ACID 준수, SQL의 전체 기능을 제공한다 — 스택에 새 시스템을 추가하지 않고도.

다음 단계:

  1. 기존 PostgreSQL 인스턴스에서 pgvector 활성화 (CREATE EXTENSION vector;).
  2. 문서 테이블에 벡터 컬럼과 HNSW 인덱스 추가.
  3. 임베딩을 로드하고 이 가이드의 튜닝 벤치마크 실행.
  4. 프로덕션 RAG를 위해 LangChain이나 LlamaIndex와 통합.

Telegram 커뮤니티에 가입하여 pgvector 성능 수치를 공유하고 동료 엔지니어로부터 도움을 받아라.

출처 및 추가 자료 #

  1. pgvector GitHub 저장소 — https://github.com/pgvector/pgvector (15,000+ Stars)
  2. pgvector 문서 — https://github.com/pgvector/pgvector?tab=readme-ov-file#pgvector
  3. PostgreSQL 18 릴리스 노트 — https://www.postgresql.org/docs/18/release-18.html
  4. Supabase Vector 문서 — https://supabase.com/docs/guides/ai
  5. HNSW 논문 (Malkov & Yashunin, 2018) — https://arxiv.org/abs/1603.09320
  6. pgvector HNSW 프로덕션 튜닝 튜토리얼 2026 — https://nerdleveltech.com/pgvector-hnsw-postgres-18-production-tuning-tutorial
  7. 2026 벡터 데이터베이스 벤치마크 — https://iotdigitaltwinplm.com/vector-database-benchmarks-2026/

추천 호스팅 및 인프라 #

위 도구들을 프로덕션에 배포하려면 안정적인 인프라가 필요합니다. dibi8가 직접 사용 중인 두 가지 옵션:

  • DigitalOcean — 60일 $200 무료 크레딧, 14개 이상 글로벌 리전. 오픈소스 AI 도구의 기본 선택.
  • HTStack — 홍콩 VPS, 중국 본토 저지연 접속. dibi8.com 호스팅 중인 검증된 IDC.

제휴 링크 — 추가 비용 없이 dibi8 운영을 지원합니다.

제휴 공개 #

이 문서에는 클라우드 호스팅을 위한 DigitalOcean 및 관리형 PostgreSQL을 위한 Supabase 제휴 링크가 포함되어 있다. 우리 링크를 통해 가입하면 추가 비용 없이 커미션을 받는다. 우리는 자체 프로덕션 환경에서 사용하는 서비스만 추천한다.

💬 댓글 토론