Pg_vectorsearch: An index that is faster than pgvector's IVFFlat and HNSW
pg_vectorsearch: pgvector의 IVFFlat·HNSW보다 빠른 인덱스
Timescale이 PostgreSQL용 근사 최근접 이웃 검색 확장 pg_vectorsearch를 공개했습니다. PRISM 인덱스는 계층형 클러스터링과 RaBitQ 양자화로 검색과 인덱스 생성을 빠르게 하며, 기존 pgvector 테이블에도 적용할 수 있지만 현재 알파 버전으로 PostgreSQL 18 이상이 필요합니다.
- 주제
에디터 노트
PRISM의 속도 주장은 재현율을 맞춘 1억 벡터 비교와 4분의 1 메모리 사용이라는 조건을 함께 제시합니다. 다만 제공된 저장소 설명에는 QPS, 데이터셋 구성, 하드웨어와 재현율 측정 방식이 없어 수치를 독립적으로 판단하기 어렵습니다. Hacker News에서 벤치마크를 찾기 어렵다는 지적이 나온 것도 이 정보가 README에서 바로 드러나지 않기 때문입니다. 실제 도입 여부는 성능 주장 외에도 필터링과 운영 환경에 달려 있습니다. 멀티테넌트용 다중 컬럼 인덱스는 향후 계획이고, 목록 재균형도 별도 작업이 필요합니다. PostgreSQL 18 이상을 요구하는 알파 확장이라 관리형 데이터베이스 이용자에게는 선택지가 제한될 수 있습니다. pgvectorscale의 재현율 문제를 이유로 아키텍처를 바꿨다는 설명은 방향 전환의 근거지만, 기존 사용자가 겪은 문제의 조건과 새 인덱스의 비교 자료가 더 구체적으로 공개돼야 교체 판단에 도움이 됩니다.
AI 요약
pg_vectorsearch는 PostgreSQL에서 고성능 근사 최근접 이웃(ANN) 검색을 지원하는 C 확장입니다. PRISM(Partitioned Routing Index for Similarity Matching)은 IVFFlat과 비슷한 분할형 인덱스 구조에 계층형 라우팅과 RaBitQ 양자화를 적용합니다. 프로젝트는 검색과 인덱스 생성 모두 pgvector의 IVFFlat과 HNSW보다 빠르다고 주장합니다. 1억 개 벡터 데이터셋에서 HNSW와 재현율이 비슷한 조건으로 비교했을 때 메모리를 4분의 1만 사용했다고 설명합니다.
검색 과정과 인덱스 구성
PRISM은 계층형 중심점 트리를 따라 가까운 클러스터를 찾고, 각 클러스터의 posting list에서 후보 벡터를 검색합니다. 중심점 트리와 목록은 PostgreSQL 버퍼 캐시를 활용하며 후보 검색에는 비동기 I/O도 사용합니다. 벡터는 RaBitQ로 양자화해 저장하고, AVX2·AVX512·NEON 기반 SIMD 거리 계산으로 후보를 빠르게 추립니다. RaBitQ는 오차 범위를 제공해 가장 가까운 이웃이 될 수 없는 후보를 제거합니다. 남은 벡터는 테이블에 저장된 원본 정밀도 값으로 재정렬한 뒤 상위 k개를 반환합니다.
인덱스는 생성 시점의 행 수를 기준으로 크기를 정합니다. 따라서 데이터를 먼저 적재하고 인덱스를 만드는 방식을 안내합니다. 기본값인 prism.nprobe는 검색할 클러스터 수를 조정하며, 문서에서는 기본 설정이 대략 0.95 재현율을 목표로 한다고 설명합니다. 값을 높이면 재현율을 높이고 낮추면 속도를 높이는 방향으로 조정합니다.
기존 pgvector 테이블과 운영 조건
새 테이블에는 확장이 제공하는 vec32 또는 vec16 자료형을 쓸 수 있습니다. 기존 pgvector의 vector·halfvec 컬럼도 다시 쓰거나 복사하지 않고 PRISM 인덱스를 만들 수 있습니다. 두 확장을 함께 설치해 기존 쿼리와 거리 연산자를 유지하는 방식입니다. L2, 내적, 코사인 거리 연산을 지원하며 기존 HNSW 인덱스의 거리 연산자 클래스에 맞춰 PRISM 연산자 클래스를 선택해야 합니다. vec16은 vec32보다 벡터 저장 공간을 절반으로 줄입니다.
동적 삽입·수정·삭제를 지원하지만, 새 데이터는 해당 posting list에 추가되고 목록은 자동 분할되지 않습니다. 커진 목록을 나누려면 prism_rebalance를 실행해야 합니다. 현재 알파 버전이며 운영 환경보다는 테스트용입니다. 사전 공개 버전 사이의 업그레이드가 보장되지 않으므로 확장과 인덱스를 삭제한 뒤 다시 만들어야 할 수 있습니다. 빌드 요구사항은 PostgreSQL 18 이상이며, C 컴파일러와 Meson이 필요합니다.
Hacker News 반응
- @Rapzid — 필터링도 지원하나요? 댓글을 보면 사후 필터링만 지원하는 것 같은데, 인덱스에서 테넌트·사용자·권한 범위를 효율적으로 처리하는 방법을 모르겠습니다.
- @enordstr — 멀티테넌트 테이블용 다중 컬럼 인덱스는 향후 버전에서 계획하고 있습니다.
- @EgregiousCube — 지금 VectorChord를 쓰고 있는데 만족합니다. 빠른 저장 장치와 함께 쓰니 PostgreSQL 비용을 절반으로 줄였습니다. 메모리를 적게 쓰는 벡터 인덱스 경쟁이 반갑습니다.
- @esafak — 빠르다는 주장보다 벤치마크를 먼저 보여줘야 하지 않나요? QPS와 정밀도·재현율 수치를 보고 싶습니다.
- @jascha_eng — 벤치마크는 블로그 글에 있고, 측정 도구도 함께 공개했습니다.
- @esafak — README에서 blog나 benchmark라는 단어를 검색해도 나오지 않습니다. 쉽게 찾을 수 있게 해야 합니다.
- @mfreed — pgvectorscale은 그래프 기반 인덱스였지만 일부 데이터셋에서 그래프 일부에 도달할 수 없어 재현율이 떨어지는 문제가 있었습니다. 해결책을 찾지 못해 분할형 구조와 압축을 쓰는 새 아키텍처로 옮겼으며, pgvectorscale은 유지보수 모드에 들어갑니다.
- @panzi — pg_vectorsearch가 1968차원보다 큰 벡터도 지원할 계획인가요? 이번에는 왜 Rust 대신 C를 썼나요? 기존 확장에 새 인덱스 유형을 추가하지 않고 별도 확장으로 만든 이유도 궁금합니다.
- @devy — 기존 HNSW를 대체하려는 경우 차원 제한, PostgreSQL 18 이상 요구사항, 알파 단계라는 점이 걸립니다. 오래된 PostgreSQL이나 관리형 데이터베이스에서는 바로 시험하기 어려울 수 있습니다.
- @mfreed — pgvector 프로젝트는 당시 기존 인덱스 유형에 집중하려는 방향이었습니다. 별도 확장으로 만들면 서로 다른 설계를 시도할 수 있고, pgvector 자료형도 그대로 쓸 수 있습니다.
- @trnvll — 속도가 중요하면서도 PostgreSQL 안에서 간단하게 개발하고 싶은 프로젝트가 있어 써보고 싶습니다.
원문: GitHub / 번역·요약: Trawling