[PostgreSQL] Vector Search를 위한 인덱스 타입 비교 (HNSW vs IVFFlat)
2024. 11. 14. 21:35ㆍRDBMS
서론
안녕하세요! 요즘 AI 시대를 맞이하여 벡터 검색(Vector Search)이 정말 핫한데요. PostgreSQL에서도 pgvector 확장을 통해 벡터 검색을 지원하고 있습니다. 오늘은 벡터 검색에 사용되는 두 가지 주요 인덱스 타입인 HNSW와 IVFFlat에 대해 알아보겠습니다.
무엇이 다를까?
우선 두 인덱스의 주요 특징을 간단히 비교해볼까요?
HNSW (Hierarchical Navigable Small World)
- 그래프 기반 인덱스
- 빠른 검색 속도
- 더 많은 메모리 사용
- 인덱스 생성이 더 오래 걸림
IVFFlat (Inverted File Flat)
- 클러스터 기반 인덱스
- 적은 메모리 사용
- 빠른 인덱스 생성
- HNSW보다는 조금 느린 검색 속도
실제 사용 예제
간단한 예제로 두 인덱스의 사용법을 살펴보겠습니다.
-- pgvector 확장 설치
CREATE EXTENSION vector;
-- 테스트용 테이블 생성
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
content TEXT,
embedding vector(1536) -- OpenAI의 embedding 차원
);
-- HNSW 인덱스 생성
CREATE INDEX hnsw_idx ON documents
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
-- IVFFlat 인덱스 생성
CREATE INDEX ivf_idx ON documents
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);
각 인덱스의 동작 원리
HNSW의 동작 방식
-- HNSW 검색 예제
SELECT content,
1 - (embedding <=> '[vector_values]') as similarity
FROM documents
ORDER BY embedding <=> '[vector_values]'
LIMIT 5;
HNSW는 다음과 같이 동작합니다:
- 계층적 그래프 구조 생성
- 상위 레이어에서 하위 레이어로 이동하며 검색
- 각 노드는 이웃 노드들과 연결
주요 파라미터:
- m: 노드당 최대 이웃 수
- ef_construction: 인덱스 생성 시 정확도
IVFFlat의 동작 방식
-- IVFFlat 검색 예제
SET ivfflat.probes = 10; -- 검색할 클러스터 수 설정
SELECT content,
1 - (embedding <=> '[vector_values]') as similarity
FROM documents
ORDER BY embedding <=> '[vector_values]'
LIMIT 5;
IVFFlat은 다음과 같이 동작합니다:
- 데이터를 여러 클러스터로 분할
- 쿼리 벡터와 가장 가까운 클러스터 선택
- 선택된 클러스터 내에서 검색
주요 파라미터:
- lists: 클러스터 수
- probes: 검색할 클러스터 수
성능 비교
간단한 벤치마크 결과를 보여드리겠습니다:
-- 100만 개의 벡터에 대한 검색 성능 테스트
EXPLAIN ANALYZE
SELECT id, 1 - (embedding <=> '[vector_values]') as similarity
FROM documents
ORDER BY embedding <=> '[vector_values]'
LIMIT 10;
일반적인 성능 특성
- 검색 시간
- HNSW: ~5-10ms
- IVFFlat: ~20-30ms
- 메모리 사용량
- HNSW: 원본 데이터의 약 50-100%
- IVFFlat: 원본 데이터의 약 20-30%
어떤 상황에서 어떤 인덱스를 선택할까?
HNSW 선택 시기
- 검색 속도가 최우선일 때
- 메모리 자원이 충분할 때
- 높은 정확도가 필요할 때
- 실시간 검색이 필요할 때
IVFFlat 선택 시기
- 메모리 사용량이 중요할 때
- 빠른 인덱스 생성이 필요할 때
- 약간의 검색 시간 증가를 감수할 수 있을 때
- 대규모 데이터셋을 다룰 때
주의할 점
- 인덱스 생성 시간 고려하기
- 메모리 사용량 모니터링하기
- 정기적인 VACUUM ANALYZE 실행하기
- 적절한 파라미터 튜닝하기
마치며
저는 실제로 두 인덱스를 모두 적용한뒤 RAG 평가 도구를 사용해서 실제 검증후 사용하고 있습니다. 여러분도 적용과 함깨 RAG를 테스트하여 각 어플리케이션에 맞는 인덱스 선택이 필요하다고 생각합니다!
다음에는 벡터 검색의 성능 최적화 팁에 대해 다뤄보도록 하겠습니다. 감사합니다! 😊
'RDBMS' 카테고리의 다른 글
[PostgreSQL] 인덱스(Index)의 기초 이해하기 (2) | 2024.11.14 |
---|---|
[AWS Redshift] FULL JOIN과 COALESCE (0) | 2024.03.08 |
MSSQL - DataBase내부 테이블들의 용량/row수 확인하기 (0) | 2022.05.07 |
MSSQL - 날짜 및 시간 더하고 빼기 (0) | 2022.01.04 |
MSSQL - 현재 날짜 시간 구하기 (0) | 2022.01.04 |