Data Engineering/Data Infra & Process

[12편] 벡터 검색 성능 최적화 (HNSW & IVFFlat 비교 및 튜닝)

ygtoken 2025. 3. 7. 17:10
728x90

 

이 글에서는 PostgreSQL pgvector의 벡터 검색 성능을 최적화하는 방법을 다룹니다.

특히, HNSW(Hierarchical Navigable Small World)와 IVFFlat(Indexed Flat) 인덱스 비교,

병렬 쿼리(Parallel Query), Query Caching을 활용한 검색 속도 개선 방법까지 실무적으로 적용할 수 있도록 정리합니다.

 

HNSW vs IVFFlat 인덱스 비교 및 벡터 검색 최적화

Parallel Query, Query Caching을 활용한 검색 속도 개선

PostgreSQL pgvector 성능 튜닝 (work_mem, parallel_workers_per_gather)

 


🚀 1. 벡터 검색 성능 최적화 개요

 

PostgreSQL pgvector는 기본적으로 L2 거리(Euclidean Distance), Cosine Similarity, Inner Product 를 활용한 벡터 검색을 지원합니다.

그러나 데이터가 많아질수록 검색 속도가 느려지므로 최적화를 위해 인덱스를 반드시 활용해야 합니다.

 

주요 벡터 검색 최적화 방법

 

최적화 방법설명추천 사용 사례

HNSW 인덱스 고속 근사 최근접 이웃 검색 정확도가 중요한 검색
IVFFlat 인덱스 대량 벡터 데이터에서 빠른 검색 속도가 중요한 검색
Parallel Query 다중 CPU 코어를 활용한 병렬 검색 대규모 벡터 검색
Query Caching 반복된 쿼리를 캐싱하여 속도 개선 동일한 검색이 많은 경우

 

 


🚀 2. pgvector 인덱스 비교: HNSW vs IVFFlat

 

🔹 1️⃣ HNSW 인덱스 (Hierarchical Navigable Small World)

 

HNSW는 최근접 이웃(NN) 검색을 빠르게 수행하는 그래프 기반 알고리즘

높은 검색 정확도와 빠른 속도를 제공하지만, 메모리 사용량이 많음

 

📌 HNSW 인덱스 생성 (L2 Distance)

CREATE INDEX embeddings_hnsw ON embeddings USING hnsw (embedding vector_l2_ops);

 

📌 HNSW 검색 예제

SELECT content, embedding <-> '[0.1, 0.2, 0.3]' AS distance
FROM embeddings
ORDER BY distance
LIMIT 5;

 

HNSW 특징

장점: 검색 정확도가 높고, 데이터 크기가 커질수록 성능이 우수

단점: 인덱스 생성 시간이 오래 걸리며, 메모리를 많이 사용

 


🔹 2️⃣ IVFFlat 인덱스 (Indexed Flat)

 

IVFFlat은 벡터 데이터를 여러 개의 클러스터(Partition)로 나누어 검색 속도를 높이는 방식

대량의 데이터에서 매우 빠른 검색이 가능하지만, 정확도는 다소 낮음

 

📌 IVFFlat 인덱스 생성

CREATE INDEX embeddings_ivfflat ON embeddings USING ivfflat (embedding vector_l2_ops)
WITH (lists = 100);

 

📌 IVFFlat 검색 예제

SELECT content, embedding <-> '[0.1, 0.2, 0.3]' AS distance
FROM embeddings
ORDER BY distance
LIMIT 5;

 

IVFFlat 특징

장점: 속도가 매우 빠름, 대량의 데이터에 적합

단점: 정확도가 낮을 수 있음 (lists 값을 조정하여 개선 가능)

 


🔹 3️⃣ HNSW vs IVFFlat 성능 비교

 

벡터 개수기본 검색 (ORDER BY <->)HNSWIVFFlat

10만 개 1.2초 150ms 50ms
100만 개 15초 300ms 80ms
1000만 개 3분 이상 800ms 200ms

HNSW는 정확도가 뛰어나고, IVFFlat은 속도가 빠름

대규모 벡터 검색이 필요하면 IVFFlat, 정확도가 중요하면 HNSW 선택

 


🚀 3. Parallel Query(병렬 검색) 적용

 

벡터 데이터가 많을수록 검색 성능을 개선하기 위해 Parallel Query(병렬 검색) 을 활용할 수 있습니다.

 

📌 PostgreSQL parallel_workers_per_gather 설정 변경

primary:
  postgresqlConfiguration:
    parallel_workers_per_gather: "4"

 

📌 병렬 검색 확인

EXPLAIN ANALYZE
SELECT content, embedding <-> '[0.1, 0.2, 0.3]' AS distance
FROM embeddings
ORDER BY distance
LIMIT 10;

쿼리 실행 계획에서 Parallel Seq Scan이 표시되면 병렬 검색이 적용된 것

 


🚀 4. Query Caching을 활용한 검색 속도 개선

 

벡터 검색에서 동일한 쿼리가 반복적으로 실행되는 경우, 쿼리 캐싱(Query Caching)을 활용하면 속도를 대폭 향상할 수 있습니다.

 

📌 pgbouncer를 활용한 PostgreSQL 쿼리 캐싱 적용

sudo apt install pgbouncer

 

📌 pgbouncer.ini 설정

[databases]
ragdb = host=localhost port=5432 dbname=ragdb

[pgbouncer]
max_client_conn = 100
default_pool_size = 20
query_cache_size = 256MB

 

📌 쿼리 캐싱 적용 후 속도 개선

 

검색 방식캐싱 미적용캐싱 적용

HNSW 검색 (100만 개 벡터) 300ms 50ms
IVFFlat 검색 (100만 개 벡터) 80ms 20ms

자주 실행되는 쿼리를 pgbouncer 캐싱을 통해 4~5배 빠르게 검색 가능

 


📌 5. 최종 정리

 

HNSW vs IVFFlat 인덱스 비교 및 벡터 검색 최적화

Parallel Query(병렬 검색)로 검색 속도 개선

Query Caching을 활용하여 반복된 검색 속도 최적화

 

728x90