pg_vectorsearch: Timescale의 PRISM 인덱스가 pgvector IVFFlat 및 HNSW보다 빠른 벡터 검색을 주장
Timescale은 오픈소스 PostgreSQL 확장 프로그램인 pg_vectorsearch를 출시했습니다. 이 확장 프로그램은 PRISM이라는 새로운 근사 최근접 이웃 인덱스를 제공하며, 프로젝트는 pgvector의 IVFFlat 및 HNSW보다 쿼리와 인덱스 구축 모두에서 훨씬 빠르다고 주장합니다. 이 확장 프로그램은 명시적으로 알파 단계로 표시되어 있으며 프로덕션보다는 테스트용으로 설계되었지만, HNSW의 그래프 탐색 대신 파티셔닝과 압축을 사용하는 독특한 아키텍처 선택을 도입합니다.
pg_vectorsearch란 무엇인가
pg_vectorsearch는 고성능 근사 최근접 이웃(ANN) 검색을 위한 PostgreSQL 확장 프로그램으로, Timescale이 PostgreSQL 라이선스로 게시했습니다. 핵심 구성 요소는 PRISM(Partitioned Routing Index for Similarity Matching)으로, C로 구현된 PostgreSQL 네이티브 인덱스 접근 방식입니다.
확장 프로그램의 명시된 기능 세트는 다음과 같습니다:
- PRISM 인덱스 — 1억 개 이상의 벡터용, IVF 스타일, 계층적 라우팅 포함
- RaBitQ 양자화 — 2단계 검색을 위한 이론적 오류 경계 포함
- SIMD 최적화 거리 계산 (AVX2, AVX512, NEON)
- 동적 업데이트 — 삽입, 업데이트, 삭제,
prism_rebalance를 통한 포스팅 목록 분할 - pgvector 호환성 — 기존
vector및halfvec열을 그대로 인덱싱 가능
저장소에는 눈에 띄는 상태 경고가 있습니다: "상태: 알파. 테스트용이지 프로덕션용이 아님. 프리릴리스 간 업그레이드는 불가능할 수 있음; 확장 프로그램과 인덱스를 삭제하고 다시 생성할 계획을 세우십시오."
PRISM 인덱스 작동 방식
PRISM은 개념적으로 pgvector의 IVFFlat과 유사하지만, IVFFlat의 평평한 센트로이드 목록을 계층적 센트로이드 트리로 대체하고 양자화 기반 필터링을 추가합니다. Timescale은 결과를 "쿼리와 인덱스 구축 모두에서 pgvector의 IVFFlat 및 HNSW보다 훨씬 빠른 인덱스"라고 설명합니다.
인덱스는 계층적 센트로이드 트리를 사용하여 벡터를 클러스터로 분할하고, PostgreSQL 버퍼 캐시에 의존하여 해당 트리를 메모리에 유지합니다. 벡터는 RaBitQ로 양자화되어 SIMD 거리 계산에 최적화된 페이지 레이아웃으로 포스팅 목록에 저장됩니다. RaBitQ 인코딩은 오류 경계를 제공하여 검색이 최근접 이웃이 될 수 없는 벡터를 제외할 수 있으므로, 테이블에 저장된 전체 정밀도 값에 대해 재순위화해야 하는 벡터 수가 훨씬 줄어듭니다.
문서화된 쿼리 흐름은 다음과 같습니다:
쿼리 흐름:
1. 최근접 클러스터를 찾기 위해 센트로이드 트리 탐색 (버퍼 캐시)
2. 후보자 스캔을 위한 포스팅 목록 검색 (버퍼 캐시, 비동기 I/O)
3. RaBitQ 2단계 필터링: 추정 → 오류 경계 → 재순위화
4. 힙에서 전체 정밀도 재순위화
5. k개의 최근접 이웃 반환
프로젝트는 RaBitQ(SIGMOD 2024), SPFresh의 LIRE 프로토콜(SOSP 2023), SPANN(NeurIPS 2021), Google의 ScaNN for AlloyDB 백서를 연구 기반으로 인용합니다.
성능 주장
Timescale의 동반 발표 블로그 게시물은 구체적인 벤치마크 주장을 합니다. 확장 프로그램 작성자 jascha_eng는 Hacker News에서 해당 게시물의 요약을 인용했습니다:
TLDR: 우리는 pg_vectorsearch를 출시합니다. 벡터 검색을 획기적으로 더 빠르고 비용 효율적으로 만드는 새로운 오픈소스 PostgreSQL 확장 프로그램입니다. 새로운 PRISM 인덱스는 HNSW의 그래프 기반 접근 방식 대신 파티셔닝과 압축을 사용하여 쿼리 속도를 높이고 메모리 사용량을 줄이며 인덱스 구축을 훨씬 빠르게 제공합니다. 1억 개의 벡터에서 PRISM은 HNSW보다 메모리가 4배 적은 머신에서 6ms 쿼리 지연 시간을 달성했으며 인덱스 구축은 20배 이상 빨랐습니다.
GitHub README는 "그래프 기반 HNSW와 비교할 때, PRISM은 메모리가 4분의 1인 인스턴스에서 1억 개 벡터 데이터셋에 대해 동등한 재현율에서 더 빠릅니다."라고 명시합니다.
Hacker News 댓글 작성자 esafak은 숫자가 제시되는 방식에 반발하며 벤치마크가 먼저 나와야 한다고 주장했습니다: "빠르다면 벤치마크를 먼저 보여주지 않아야 하나? qps와 정밀도/재현율을 보여주세요." 저장소 자체는 스크랩된 콘텐츠에서 전체 QPS 대 재현율 테이블을 재현하지 않으며, 발표 게시물과 튜닝 가이드에 링크합니다.
설치 및 사용법
pg_vectorsearch는 개발 헤더가 있는 PostgreSQL 18 이상, GNU C11 컴파일러(GCC 11+ 또는 Clang 14+), Meson 빌드 시스템이 필요합니다. CBLAS는 선택 사항이지만 RaBitQ 인코딩 속도를 높입니다.
# 릴리스 빌드
meson setup builddir --buildtype=release
# PostgreSQL에 빌드 및 설치
meson install -C builddir
두 가지 사용 경로가 있으며, 둘 다 동일한 인덱스를 구축하고 동일한 연산자(<->, <#>, <=>)와 튜닝 노브를 사용합니다.
네이티브 타입
새로 시작하거나 pgvector를 사용하지 않는 경우, 벡터를 pg_vectorsearch 자체의 vec32(float32) 또는 vec16(float16) 열에 저장합니다. 다른 확장 프로그램은 필요 없습니다.
CREATE EXTENSION pg_vectorsearch;
-- PLAIN은 벡터를 인라인으로 유지합니다. EXTERNAL(기본값)은 약 2kB 이상의 값을 토스트하고,
-- 재순위화는 플래너가 비용을 계산하지 않는 추가 페치를 지불합니다.
CREATE TABLE items (
id serial PRIMARY KEY,
embedding vec32(3) STORAGE PLAIN
);
-- 먼저 로드하세요; 인덱스는 CREATE INDEX 시점의 행 수로 크기가 결정됩니다.
-- 플래너가 인덱스를 사용하려면 500행이면 충분합니다.
INSERT INTO items (embedding)
SELECT ARRAY[i::real, (i % 7)::real, (i % 5)::real]::vec32
FROM generate_series(1, 1000) i;
-- 내적 또는 코사인의 경우 아래 Operator classes를 참조하세요.
CREATE INDEX ON items USING prism (embedding vec32_l2_ops);
-- 0 = 자동 (약 0.95 재현율). 재현율을 높이려면 올리고, 속도를 높이려면 낮추세요.
SET prism.nprobe = 40;
SELECT * FROM items
ORDER BY embedding <-> '[3,1,2]'
LIMIT 5;
기존 pgvector 테이블
이미 pgvector의 vector 또는 halfvec 열이 있는 테이블이 있다면, 테이블이나 쿼리를 변경하지 않고도 PRISM 인덱스를 직접 구축할 수 있습니다. vec32와 vec16은 pgvector의 vector 및 halfvec와 바이너리 호환되지만 이름이 다르므로 두 확장 프로그램을 같은 스키마에 나란히 설치할 수 있습니다.
CREATE EXTENSION vector;
CREATE TABLE documents (
id bigserial PRIMARY KEY,
body text,
embedding vector(384)
);
CREATE INDEX documents_embedding_hnsw
ON documents USING hnsw (embedding vector_l2_ops);
-- pg_vectorsearch를 pgvector 옆에 설치하고 기존 열에 인덱스를 구축하세요.
-- 열은 다시 쓰거나 복사되지 않습니다.
CREATE EXTENSION pg_vectorsearch;
CREATE INDEX documents_embedding_prism
ON documents USING prism (embedding vec32_l2_ops);
README는 PRISM이 일반적으로 더 빠르므로 두 인덱스가 모두 존재하는 동안 플래너가 HNSW 인덱스보다 PRISM을 선호해야 하며, 기존 인덱스를 삭제하기 전에 EXPLAIN으로 확인할 것을 권장합니다.
Operator classes
거리 측정 항목과 열 타입에 맞는 operator class를 선택하세요. L2가 기본값입니다.
| 거리 | 연산자 | vec32 / vector |
vec16 / halfvec |
|---|---|---|---|
| L2 | <-> |
vec32_l2_ops |
vec16_l2_ops |
| 내적 | <#> |
vec32_ip_ops |
vec16_ip_ops |
| 코사인 | <=> |
vec32_cosine_ops |
vec16_cosine_ops |
HNSW 인덱스를 교체할 때, pgvector의 vector_<metric>_ops는 vec32_<metric>_ops로, halfvec_<metric>_ops는 vec16_<metric>_ops로 매핑됩니다.
튜닝 및 유지보수
기본값은 대규모 벤치마크에서 튜닝되었으며, 문서에 따르면 대부분의 배포는 prism.nprobe만 조정합니다. prism.nprobe = 0으로 설정하면 약 0.95 재현율을 목표로 하는 자동 값을 선택합니다.
유지보수에 대해 README는 삽입 시 벡터가 라우팅되는 포스팅 목록에 추가되므로, 행이 도착함에 따라 목록이 커지고 자체적으로 분할되지 않는다고 설명합니다. REINDEX 외에도 prism_rebalance 프로시저가 과도하게 큰 목록을 제자리에서 분할합니다.
커뮤니티에서 제기된 채택 제약 사항
Hacker News 댓글 작성자 devy는 기존 pgvector HNSW 인덱스를 교체하려는 모든 사람에게 세 가지 실질적인 장애물을 정리했습니다:
- pg_vectorsearch는 PRISM이라는 양자화된 IVF 인덱스를 사용합니다. PRISM은 벡터 차원을 1968로 제한합니다. 기존 HNSW 인덱스가 그보다 더 많은 차원을 가지고 있다면, (적어도 그들이 수정할 때까지는) 방법이 없습니다.
- pg_vectorsearch는 PostgreSQL 18 이상이 필요합니다. 그보다 낮은 PG 버전을 사용한다면 먼저 데이터베이스를 마이그레이션해야 합니다. 많은 레거시 PG 프로덕션 환경은 PG 14 또는 15에 크게 뒤처져 있으며, 마이그레이션은 이것을 시도하기에는 엄청난 비용이 듭니다.
- pg_vectorsearch는 어제 출시되었고 분명히 알파 단계입니다. Timescale 외부의 프로덕션 환경에서 전투 테스트되지 않았습니다. 또한 너무 새롭기 때문에 Azure의 허용 확장 프로그램 목록이나 다른 Hyperscale 관리형 PG 인스턴스의 허용 확장 프로그램 목록에 없습니다.
세 번째 요점은 swe_dima가 반향했습니다: "안타깝게도 클라우드 제공업체가 관리형 postgres에서 제공하지 않으면 많은 사람들이 사용할 수 없습니다..."
필터링, 양자화 및 공개 질문
여러 댓글 작성자가 README에서 광고하지 않는 기능을 언급했습니다. Rapzid는 인덱스가 필터링을 지원하는지 물었고 문서를 통해 사후 필터링만 가능하다고 결론지었습니다: "필터링을 지원하나요? 편집: 사후 필터링만 가능. 사람들이 이러한 인덱스로 테넌트/사용자/권한 범위를 효율적으로 구현하는 방법을 이해할 수 없습니다."
potomushto는 이진 양자화와 해밍 거리 지원이 없다는 점을 언급했습니다: "흥미롭네요. 비트 정밀도와 해밍 거리 연산자에 대한 언급이 전혀 없는데, 이는 훨씬 빠르고 저장 효율적일 것으로 예상됩니다."
다른 사람들은 프로젝트가 게시하지 않은 비교를 요청했습니다. thomasahle은 PRISM이 Roar 그래프와 어떻게 비교되는지, dmix는 ParadeDB의 pg_search와 어떻게 비교되는지, jakobedding은 pgvectorscale과 어떻게 비교되는지 물었습니다. arunmu는 더 나아가 전략에 의문을 제기했습니다: "이 사람들이 지금 유지되지 않는 것처럼 보이는 pgvectorscale도 작성하지 않았나요? pgvectorscale에 추가하거나 개선하는 대신 왜 새 인덱스를 만드는 거죠?"
경쟁 구도
댓글 작성자 EgregiousCube는 프로덕션에서 VectorChord를 실행 중이라고 보고하며 이 출시를 메모리 효율적인 인덱스로의 더 넓은 추세의 일부로 설명했습니다: "저는 현재 VectorChord를 실행 중이고 정말 좋아합니다 - 빠른 백업 디스크로 Postgres 비용이 절반으로 줄었습니다. 저RAM 벡터 인덱스 도구에서 경쟁을 보게 되어 기쁩니다. RAMageddon은 현대 nvme 드라이브의 속도를 활용할 더 많은 방법을 찾도록 인센티브를 만드는 것 같습니다!"
ilumanty는 PostgreSQL 외부에 동일한 클래스의 인덱스가 존재하기를 바라는 반대의 소망을 표현했습니다: "SQLite가 이런 종류의 기능을 지원한다면 정말 멋질 텐데요."
alexpadula의 가벼운 관찰은 저장소의 PRISM 로고 이미지를 언급했습니다: "PRISM의 다크 사이드! 저장소의 이미지는 100% Pink Floyd의 Dark Side of The Moon에서 영감을 받았습니다."
핵심 요점
pg_vectorsearch는 PostgreSQL 18+ 확장 프로그램으로, HNSW의 그래프 구조를 계층적 IVF 스타일 파티션 트리와 오류 경계 필터링이 있는 RaBitQ 양자화로 교체합니다. Timescale 자체 수치에 따르면 HNSW보다 메모리가 4배 적은 머신에서 1억 개 벡터에 대해 6ms 쿼리 지연 시간을 달성하고 인덱스 구축은 20배 이상 빠릅니다. 반면, 이 확장 프로그램은 알파 단계이고 PostgreSQL 18이 필요하며, 관리형 클라우드 허용 목록에 아직 없고, 커뮤니티 보고에 따르면 1968 차원으로 제한되며 필터링된 검색보다는 사후 필터링을 지원합니다. 이 프로젝트는 열 수준에서 pgvector와 호환되므로 테이블이나 쿼리를 다시 작성하지 않고 기존 HNSW 인덱스와 함께 평가할 수 있습니다.