Yebali

pgvector 톺아보기 본문

Backend Common

pgvector 톺아보기

예발이 2025. 12. 29. 15:56

pgvector란?

pgvector는 PostgreSQL에서 벡터(Vector) 데이터를 저장하고 유사도 검색을 수행할 수 있도록 해주는 확장(Extension)이다.

주로 임베딩(Embedding) 데이터를 저장하고, 이를 기반으로 코사인 유사도, 내적, 거리 계산 등의 연산을 수행하는 데 사용된다.

최근 LLM, 추천 시스템, 시맨틱 검색(RAG)과 같은 분야에서는 텍스트·이미지·음성 데이터를 숫자 벡터로 변환해 비교하는 방식이 널리 사용되고 있다.

pgvector는 이러한 벡터 연산을 별도의 벡터 DB 없이 PostgreSQL 내부에서 처리할 수 있도록 해주며,
기존 관계형 데이터와 벡터 검색을 함께 활용할 수 있다는 장점이 있다.

 

pgvector의 기능

데이터 타입 (Vector Types)

pgvector는 PostgreSQL에서 벡터 데이터를 효율적으로 저장하고 검색하기 위해 총 4가지 벡터 타입을 제공한다.

이를 통해 고차원 임베딩 벡터를 테이블 컬럼으로 직접 저장할 수 있다.

 

1. vector (32-bit float, Default)

가장 기본이 되는 벡터 타입으로, 32-bit float(float4) 기반의 실수 벡터이다.

embedding vector(1536)

 

 

주로 텍스트임베딩, RAG, 시맨틱 검색에 사용 된다.

정밀도가 높고 대부분의 pgvector의 모든 연산 및 인덱싱 기능을 안정적으로 지원한다.

 

하지만 벡터 차원이 커질수록 메모리 및 디스크 사용량이 증가하고,
대규모 데이터 셋에서는 저장 비용이 크다는 단점이 있다.

 

2. halfvec (16-bit float)

embedding halfvec(1536)

16-bit float(float2) 기반의 벡터 타입으로, vector 대비 절반의 메모리를 사용한다.

 

대규모 임베딩이 저장되는 곳에 적합하며 약간의 정밀도 손실이 허용되는 검색 시스템이나 

메모리 사용량이 중요한 환경에서 주로 사용된다.

 

'vector'타입에 비해 정밀도가 낮아 유사도 계산 정확도가 다소 떨어질 수 있다.

즉, 정확도보다 규모와 비용이 더 중요한 경우에 적합하다.

 

3. bit (Binary Vector)

0과 1로만 이루어진 이진 벡터(Binary Vector) 타입이다.

embedding bit(512)

 

주로 해시기반 검색이나 Bloom Filter 등 빠른 근사 검색이 필요한 경우에 사용된다.

 

매우 작은 저장 공간을 사용하고 연산 속도가 빨라 단순한 유사성 비교에 적합하다.

하지만 일반적인 실수 기반 임베딩에는 부적합하다.

 

4. sparsevec (Sparse Vector)

대부분의 값이 0인 희소 벡터(Sparse Vector)를 효율적으로 저장하기 위한 타입이다.

embedding sparsevec(100000)

 

 

주로 TF-IDF, Bag of Words나 키워드 기반 벡터를 표현하기 위해 사용된다.

*TF-IDF: 문서 안에서 자주 등장하는 단어(TF) 이면서도 다른 문서들에서는 잘 나오지 않는 단어(IDF) 일수록 그 문서를 잘 대표한다고 보고, 그런 단어에 더 높은 점수를 주는 텍스트 표현 방법이다.

*Bag of Words: '단어의 순서는 무시하고, 각 단어가 몇 번 등장했는지만 본다.'라는 가정으로 표현하는 방법.
즉 문서를 단어 빈도 벡터로 표현하는 방법이다.

 

0 값이 많은 경우 저장공간 효율이 매우 높고 고차원 벡터 표현에 적합하다.

하지만 임베딩 기반 유사도 검색에서는 활용 빈도가 낮아 전통적인 NLP에 적합하다.

 

지원하는 연산 (Silmilarity & Distance)

pgvector는 벡터 간의 거리(distance) 및 유사도(similarity)를 계산하기 위한 다양한 연산자(operator)를 제공한다.

이러한 연산자를 활용하면 벡터 데이터를 단순히 저장하는 데 그치지 않고,

특정 벡터와 가장 유사한 벡터를 효율적으로 검색할 수 있다.

 

1. L2 Distance

유클리드 거리(Euclidean Distance)를 계산하는 연산자이다.

embedding <-> query_vector

 

벡터 사이의 직선거리를 측정하는 연산으로 값이 작을수록 유사하다.

가장 일반적인 거리 기반 유사도 측정 방식이고 좌표 기반 벡터 비교나 일반적인 머신러닝 벡터 거리 계산에 사용된다.

 

2. Cosine Distance

코사인 거리(Cosine Distance)를 계산한다. 벡터의 방향(direction) 유사도를 측정하는 방식이다.

embedding <=> query_vector

 

벡터의 방향을 측정하는 연산으로 텍스트 임베딩에서 가장 널리 사용된다. 값이 작을수록 유사하다.

주로 텍스트 임베딩 검색이나 RAG, 시맨틱 검색에 사용된다.

대부분의 LLM 기반 임베딩 검색에서는 코사인 거리가 표준처럼 사용된다.

 

3. Inner Product

벡터 내적(Inner Product)을 계산하는 연산자이다.

embedding <#> query_vector

 

백터의 크기와 방향을 함께 고려하는 연산으로 점수 기반 유사도 계산에 활용된다. 값이 작을수록 유사하다.

추천 시스템이나 랭킹 점수 기반 검색에 사용된다.

 

4. L1 Distance

L1 거리(Manhattan Distance)를 계산하는 연산자이다.

embedding <+> query_vector

 

차원의 차이를 절댓값으로 계산해 합산하는 방식이며, 값이 작을수록 유사하다.

특정 차원의 변화에 민감한 거리 계산이나 희소 벡터 비교에 사용된다.

 

5. Hamming Distance

해밍 거리(Hamming Distance)를 계산하는 연산자이다.

embedding <~> query_vector

두 이진 벡터 간에서 서로 다른 비트의 개수를 계산하며, 값이 작을수록 유사하다,.

이진 벡터(bit 타입)를 사용하는 해시 기반 검색에 활용된다.

 

6. Jaccard Distance

embedding <%> query_vector

두 이진 벡터를 집합으로 간주하여 교집합 대비 합집합의 비율을 기준으로 거리 값을 계산한다. 값이 작을수록 유사하다.

태그, 키워드 등 집합 기반 데이터의 유사도 비교에 사용된다.

 

인덱싱 (Indexing)

벡터 데이터의 개수가 많아질수록 모든 데이터를 순차적으로 비교하는 방식은 성능상 한계가 있다.

pgvector는 이를 해결하기 위해 **근사 최근접 이웃 검색(ANN, Approximate Nearest Neighbor)**을 위한 인덱스를 제공한다.

 

이를 통해 대규모 벡터 데이터에서도 유사한 벡터를 빠르게 검색할 수 있다.

IVFFlat

IVFFlat(Inverted File with Flat Compression)은 pgvector에서 가장 널리 사용되는 인덱스 방식이다.

CREATE INDEX ON documents
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);

벡터 공간을 여러 개의 리스트(lists)로 나누고, 검색 시 일부 리스트만 탐색하여 검색 속도를 크게 향상시킨다.

값이 클수록 정확도는 높아지지만, 인덱스 생성 비용과 메모리 사용량이 증가한다.

 

빠른 검색 속도가 장점이지만 근사 검색 방식(100% 정확도는 아님)이라는 한계도 존재하며 대규모 벡터 데이터에 적합하다.

 

참고로 IVFFlat 인덱스 생성 전에는 반드시 ANALYZE를 수행해야 한다.

ANALYZE 하지 않으면 매우 불균형한 클러스터를 만들어 검색 성능이 급격히 떨어질 수 있다.

HNSW (Hierarchical Navigable Small World)

HNSW(Hierarchical Navigable Small World)는 그래프 기반의 근사 최근접 탐색 인덱스이다.

CREATE INDEX ON documents
USING hnsw (embedding vector_cosine_ops);

벡터 간의 연결 관계를 그래프 구조로 구성하여, 탐색 시 효율적으로 가까운 이웃을 찾는다.

 

IVFFlat에 비해 높은 정확도와 안정적인 검색 성능을 제공한다. 하지만 메모리 사용량이 상대적으로 크다는 단점도 존재한다.

 

인덱스 사용 시 주의사항

인덱스는 사용하는 유사도 연산자에 따라 적절한 연산자 클래스를 지정해야 한다.

연산 방식 연산자 클래스
L2 Distance vector_l2_ops
Cosine Distance vector_cosine_ops
Inner Product vector_ip_ops

 

 

그리고 pgvector 인덱스는 다음 조건을 만족할 때만 사용된다.

  • ORDER BY embedding <연산자> query_vector 형태의 쿼리
  • LIMIT 절이 반드시 포함되어야 한다.

'Backend Common' 카테고리의 다른 글

Ubuntu와 RHEL에 Docker 설치하기 (On-Premise 환경 기준)  (0) 2025.06.03
Kubernetes의 ConfigMap  (0) 2024.03.16
Kubernetes의 Ingress  (0) 2024.03.16
Kubernetes의 kube-proxy  (0) 2024.03.04
Kubernetes의 Service  (0) 2024.03.03