Supabase Vector Embedding 시스템

Supabase Vector Embedding 시스템

1. 벡터 임베딩과 현대적 데이터베이스의 역할

1.1 벡터 임베딩의 개념적 토

벡터 임베딩(Vector Embedding)은 텍스트, 이미지, 오디오와 같은 비정형 데이터를 기계 학습 모델이 이해하고 처리할 수 있는 고차원의 수치 벡터(numerical vector)로 변환하는 기술적 방법론이다.1 이 과정의 핵심은 데이터가 가진 본질적인 의미, 문맥, 그리고 상호 관계를 다차원 공간상의 기하학적 관계로 치환하는 데 있다.3 즉, 복잡하고 추상적인 정보를 컴퓨터가 연산할 수 있는 형태로 정량화하는 과정이라 할 수 있다.

임베딩 모델은 대규모 데이터셋을 학습하여 특정 데이터 포인트(예: 단어, 문장, 이미지)의 특징을 포착하는 n차원의 숫자 배열, 즉 벡터를 생성한다.2 예를 들어, ’고양이’와 ’강아지’라는 단어는 생물학적, 개념적으로 유사한 특성을 공유하므로, 잘 학습된 임베딩 모델은 이 두 단어를 벡터 공간 내에서 서로 가까운 위치에 매핑한다. 반면, ’자동차’라는 단어는 이들과 의미론적 거리가 멀기 때문에 벡터 공간상에서도 멀리 떨어진 지점에 위치하게 된다.3 이처럼 임베딩은 데이터 간의 의미론적 유사성을 벡터 간의 기하학적 근접성으로 변환함으로써, 기계가 데이터의 ’의미’를 기반으로 추론하고 패턴을 발견할 수 있게 하는 근간을 제공한다.

이러한 수치적 표현은 시맨틱 검색(semantic search), 추천 시스템, 이상 탐지(anomaly detection), 데이터 분류 및 군집화 등 광범위한 인공지능 애플리케이션의 핵심 동력으로 작용한다.1

1.2 시맨틱 공간(Semantic Space)의 이해와 그 중요성

임베딩 모델이 데이터를 매핑하는 다차원 벡터 공간을 ‘시맨틱 공간(Semantic Space)’ 또는 ’의미 공간’이라 칭한다.7 이 공간에서 각 벡터는 특정 데이터 포인트의 의미론적 좌표를 나타내며, 벡터 간의 거리는 원본 데이터 간의 의미적 유사도를 정량적으로 표현한다. 시맨틱 공간의 구축은 기계가 단순히 키워드 일치 여부를 넘어, 인간과 유사한 방식으로 문맥, 뉘앙스, 유추를 분석할 수 있게 하는 패러다임의 전환을 의미한다.

예를 들어, 사용자가 “새끼 강아지“를 검색했을 때, 시스템은 ’puppy’라는 키워드가 포함된 이미지를 반환할 수 있다. 이는 “새끼 강아지“와 ’puppy’의 임베딩 벡터가 시맨틱 공간 내에서 매우 가까운 거리에 위치하기 때문에 가능한 일이다.7 이처럼 시맨틱 공간은 언어의 다의성이나 동의어 문제를 자연스럽게 해결하고, 사용자의 숨겨진 의도를 파악하여 더 정확하고 관련성 높은 결과를 제공하는 기반이 된다. 이러한 능력은 차세대 검색 엔진, 지능형 챗봇, 개인화된 추천 시스템 등 현대 AI 서비스의 품질을 결정짓는 핵심 요소로 자리 잡았다.1

1.3 관계형 데이터베이스의 진화: Postgres와 pgvector의 등장

전통적으로 관계형 데이터베이스(RDBMS)는 정형 데이터를 저장하고 관리하는 데 최적화되어 있었다. 그러나 AI 기술의 발전으로 비정형 데이터와 그로부터 추출된 벡터 임베딩을 효율적으로 처리해야 하는 새로운 요구사항이 대두되었다. 이러한 변화에 대응하여, 세계에서 가장 성숙한 오픈소스 RDBMS 중 하나인 PostgreSQL은 pgvector라는 확장 기능(extension)을 통해 벡터 데이터를 네이티브하게 지원하는 방향으로 진화했다.6

Supabase는 이러한 PostgreSQL의 확장성을 적극적으로 활용하여 자사 플랫폼의 핵심 기능으로 통합했다.9 Supabase의 접근 방식은 “이미 보유한 데이터베이스가 최고의 벡터 데이터베이스다(The best vector database is the database you already have)“라는 철학에 기반한다.9 이는 개발자가 기존의 친숙한 PostgreSQL 환경 내에서 관계형 데이터와 벡터 데이터를 함께 관리할 수 있도록 함으로써, 새로운 기술 스택을 도입하는 데 따르는 학습 곡선과 운영 복잡성을 현저히 낮추는 것을 목표로 한다.

이러한 통합적 접근은 단순한 편의성을 넘어 중요한 아키텍처적 가치를 지닌다. 별도의 전용 벡터 데이터베이스를 도입할 경우, 필연적으로 주 데이터 저장소와 벡터 저장소 간의 데이터 사일로(data silo)가 형성된다. 이는 데이터 동기화 문제, 이중 관리의 부담, 시스템 간 네트워크 지연 시간 증가, 트랜잭션 관리의 복잡성 등 다양한 운영상의 어려움을 야기한다.11 Supabase는 pgvector를 통해 벡터 데이터를 PostgreSQL 테이블의 한 컬럼으로 취급하게 함으로써, 이러한 문제들을 근본적으로 해결한다. 개발자는 단일 데이터베이스 내에서 SQL 트랜잭션을 통해 관계형 데이터와 벡터 데이터의 일관성을 보장할 수 있으며, 이는 전체 시스템 아키텍처를 단순화하고 데이터 관리의 안정성과 효율성을 크게 향상시키는 핵심적인 이점으로 작용한다.12

2. Supabase 벡터 데이터베이스의 아키텍처: pgvector 심층 분석

2.1 pgvector 확장 기능의 역할과 활성화

pgvector는 PostgreSQL에 벡터 데이터 처리를 위한 핵심 기능들을 추가하는 오픈소스 확장 기능이다. 구체적으로 vector라는 새로운 데이터 타입을 도입하고, 벡터 간의 유사도를 계산하는 다양한 연산자(operator)를 제공하며, 대규모 데이터셋에서의 빠른 검색을 위한 인덱싱(indexing) 메커니즘을 지원한다.6 Supabase는 이 pgvector를 자사 플랫폼에 긴밀하게 통합하여, 사용자가 별도의 설치 과정 없이 강력한 벡터 데이터베이스 기능을 즉시 활용할 수 있도록 한다.10

Supabase 환경에서 pgvector를 활성화하는 절차는 매우 간단하다. 사용자는 Supabase 프로젝트 대시보드의 ‘Database’ -> ‘Extensions’ 메뉴로 이동하여 ’vector’를 검색하고 활성화 버튼을 클릭하기만 하면 된다.14 또는, SQL 편집기에서 다음의 명령어를 직접 실행하여 활성화할 수도 있다.16

CREATE EXTENSION IF NOT EXISTS vector;

이 한 줄의 명령만으로 기존의 PostgreSQL 데이터베이스는 고성능 벡터 데이터베이스로서의 역량을 갖추게 된다.

2.2 핵심 데이터 타입: vector

pgvector가 활성화되면, 테이블 스키마를 정의할 때 vector라는 새로운 데이터 타입을 사용할 수 있게 된다.14 이 데이터 타입은 vector(n)과 같은 형식으로 사용되며, 여기서 n은 해당 컬럼에 저장될 벡터의 차원(dimension) 수를 의미한다. 이 차원 수는 임베딩을 생성하는 데 사용된 모델의 출력 사양과 정확히 일치해야 한다.6

예를 들어, OpenAI의 널리 사용되는 text-embedding-ada-002 모델은 1536차원의 벡터를 생성하므로, 이 모델로 생성된 임베딩을 저장할 컬럼은 다음과 같이 정의해야 한다.6

CREATE TABLE documents (
id BIGSERIAL PRIMARY KEY,
content TEXT,
embedding VECTOR(1536)
);

반면, Supabase의 Edge Functions에서 기본으로 제공되는 gte-small 모델은 384차원의 벡터를 생성한다. 따라서 이 모델을 사용할 경우에는 컬럼을 VECTOR(384)로 정의해야 한다.14

pgvector는 표준적인 고밀도 부동소수점 벡터를 위한 vector 타입 외에도 특정 사용 사례에 최적화된 다양한 데이터 타입을 지원한다. 예를 들어, halfvec은 반정밀도(half-precision) 부동소수점을 사용하여 저장 공간을 절반으로 줄일 수 있으며, bit은 이진 벡터(binary vector)를, sparsevec은 희소 벡터(sparse vector)를 효율적으로 저장하는 데 사용된다.18 이러한 다양한 타입은 메모리 사용량과 계산 효율성을 최적화해야 하는 고급 시나리오에서 유용하게 활용될 수 있다.

차원 수의 선택은 단순히 모델의 사양을 맞추는 기술적인 문제를 넘어, 시스템 전체의 성능과 비용에 직접적인 영향을 미치는 중요한 설계 결정이다. Supabase의 자체 분석에 따르면, 더 적은 차원의 임베딩이 더 나은 성능을 보이는 경향이 있다.14 고차원 벡터는 더 많은 의미 정보를 담을 수 있지만, 그만큼 더 많은 저장 공간을 차지하고 유사도 계산에 더 많은 연산 자원을 소모한다.19 이는 ‘차원의 저주(curse of dimensionality)’ 현상과 관련이 있으며,

pgvector의 인덱싱 알고리즘(IVFFlat, HNSW) 효율성에도 영향을 미친다. Supabase가 gte-small (384차원)과 같은 상대적으로 저차원 모델을 Edge Function에 내장하여 사용을 권장하는 것은 이러한 성능과 비용의 균형을 고려한 전략적 선택으로 볼 수 있다.17 따라서 애플리케이션 개발자는 임베딩 모델을 선택하는 단계에서부터 요구되는 정확도 수준과 시스템의 성능 및 비용 제약 사이에서 최적의 균형점을 찾아, 적절한 차원 수를 결정해야 한다.

2.3 지원 연산자 및 기본 쿼리

pgvector는 벡터 간의 거리를 측정하고 유사도를 비교하기 위한 세 가지 핵심적인 연산자를 제공한다.14

  • L2 거리 (Euclidean Distance): <->
  • 내적 (Inner Product): <#> (음수 내적 값을 반환)
  • 코사인 거리 (Cosine Distance): <=>

이 연산자들을 사용하여 가장 기본적인 최근접 이웃(Nearest Neighbor, NN) 검색 쿼리를 작성할 수 있다. 예를 들어, 특정 쿼리 벡터(query_vector)와 documents 테이블에 저장된 모든 임베딩 간의 L2 거리를 계산하여 가장 가까운(즉, 가장 유사한) 5개의 문서를 찾는 쿼리는 다음과 같다.

SELECT id, content
FROM documents
ORDER BY embedding <-> '[...query_vector...]'
LIMIT 5;

이 쿼리는 ORDER BY 절에서 <-> 연산자를 사용하여 각 행의 embeddingquery_vector 간의 거리를 계산하고, 그 결과를 기준으로 오름차순으로 정렬한 후 상위 5개의 결과를 반환한다.18 다른 연산자들도 동일한 방식으로 쿼리에 적용할 수 있다. 다만, <#> 연산자는 음수 내적을 반환하므로, 가장 유사한 항목(즉, 내적 값이 가장 큰 항목)을 찾기 위해서는 ORDER BY embedding <#> '[...query_vector...]' ASC와 같이 오름차순 정렬을 사용해야 한다는 점에 유의해야 한다.18

3. Supabase에서의 임베딩 생성 및 관리 패턴

Supabase 환경에서 벡터 임베딩을 생성하고 데이터베이스에 저장하는 방법론은 크게 세 가지 아키텍처 패턴으로 분류할 수 있다. 각 패턴은 구현의 복잡성, 자동화 수준, 그리고 데이터 관리 전략 측면에서 뚜렷한 장단점을 가지며, 애플리케이션의 특성에 따라 적절한 패턴을 선택하는 것이 중요하다.

3.1 패턴 1: 외부 API를 이용한 수동 임베딩 생성 및 저장 (Client-Side Embedding)

이 패턴은 가장 직관적이고 기본적인 접근 방식이다. 애플리케이션의 클라이언트 측 코드 또는 빌드 스크립트에서 직접 외부 임베딩 API(예: OpenAI API)를 호출하여 데이터를 벡터로 변환한 후, Supabase 클라이언트 라이브러리(예: supabase-js)를 사용하여 해당 벡터를 데이터베이스 테이블에 삽입(insert)하거나 갱신(update)한다.6

프로세스 예시 (Next.js 빌드 스크립트):

  1. 프로젝트 내의 문서 파일(예: .mdx 파일)들을 읽어온다.
  2. 각 문서의 내용에 대해 OpenAI API의 임베딩 엔드포인트를 호출한다.
  3. API로부터 반환된 임베딩 벡터와 원본 문서 내용을 Supabase 클라이언트의 upsert 메서드를 사용하여 documents 테이블에 저장한다.
  4. 이 스크립트를 package.jsonbuild 명령어에 포함시켜, 배포 시점에 자동으로 실행되도록 설정한다.21

장점:

  • 구현의 단순성: 프로세스가 명확하고 이해하기 쉽다.
  • 모델 유연성: OpenAI, Cohere, Hugging Face 등 원하는 어떤 임베딩 모델이든 자유롭게 선택하여 사용할 수 있다.

단점:

  • 운영 부담: 데이터가 생성되거나 수정될 때마다 개발자가 직접 임베딩 생성 및 업데이트 로직을 실행해야 한다.
  • 데이터 드리프트(Data Drift) 위험: 콘텐츠는 업데이트되었으나 해당 임베딩이 갱신되지 않는 ’데이터 드리프트’가 발생할 위험이 크다. 이러한 불일치는 시맨틱 검색 결과의 정확성을 심각하게 저하시키는 주요 원인이 된다.22

3.2 패턴 2: Supabase Edge Functions를 활용한 동적 임베딩 생성 (Server-Side, On-Demand Embedding)

이 패턴은 임베딩 생성 로직을 클라이언트에서 분리하여 Supabase가 관리하는 서버리스 환경인 Edge Functions에서 처리하는 방식이다. 클라이언트는 텍스트 데이터를 HTTP 요청을 통해 Edge Function으로 전송하고, Edge Function은 내장된 AI 추론 API를 사용하여 임베딩을 생성한 후 결과를 반환하거나 직접 데이터베이스에 저장한다.17

프로세스 예시:

  1. supabase functions new embed 명령어로 embed라는 이름의 새로운 Edge Function을 생성한다.
  2. 생성된 index.ts 파일 내에서 Supabase.ai.Session을 사용하여 임베딩 모델(gte-small) 세션을 초기화한다.
  3. HTTP POST 요청의 본문(body)에서 입력 텍스트를 추출한다.
  4. session.run(input, { mean_pool: true, normalize: true })를 호출하여 임베딩을 생성한다. mean_pool 옵션은 토큰 단위 임베딩들을 문장 전체를 대표하는 단일 벡터로 평균내어 압축하며, normalize 옵션은 벡터의 길이를 1로 만들어 코사인 유사도와 같은 거리 측정에 최적화한다.17
  5. 생성된 임베딩을 JSON 형태로 클라이언트에 응답한다.

장점:

  • 보안 강화: OpenAI API 키와 같은 민감한 자격 증명을 클라이언트 측에 노출하지 않고 서버 측에 안전하게 보관할 수 있다.
  • 클라이언트 부담 감소: 복잡한 임베딩 로직을 서버로 이전하여 클라이언트 애플리케이션을 가볍게 유지할 수 있다.
  • 인프라 통합: 모든 프로세스가 Supabase 인프라 내에서 완결되므로, 외부 API 호출에 비해 잠재적으로 네트워크 지연 시간이 짧고 비용 효율적일 수 있다.

단점:

  • 제한된 모델 지원: 현재 Supabase Edge Runtime에서 기본으로 지원하는 AI 추론 모델은 gte-small로 제한되어 있다.17 다른 모델을 사용하려면 외부 API를 직접 호출하는 로직을 구현해야 한다.

3.3 패턴 3: 트리거와 큐를 이용한 완전 자동화된 임베딩 파이프라인 (Database-Driven, Asynchronous Embedding)

이 패턴은 데이터베이스 레벨에서 임베딩 생성 및 동기화 과정을 완전히 자동화하는 가장 정교하고 안정적인 방식이다. 수동 관리의 근본적인 문제인 ’데이터 드리프트’를 원천적으로 해결하는 것을 목표로 한다.23

아키텍처 구성 요소:

  1. PostgreSQL 확장 기능:
  • pg_net: 데이터베이스 내에서 비동기 HTTP 요청을 보낼 수 있게 한다.22
  • pgmq: 경량 메시지 큐(Message Queue)를 생성하고 관리한다.22
  • pg_cron: 지정된 시간에 주기적으로 SQL 작업을 실행하는 스케줄러 역할을 한다.23
  1. 데이터베이스 트리거(Trigger):
  • 임베딩이 필요한 데이터가 저장된 테이블(예: documents)에 INSERT 또는 UPDATE 이벤트가 발생할 때마다 자동으로 실행되는 트리거를 설정한다.
  • 이 트리거는 새로 생성되거나 변경된 레코드의 ID와 같은 메타데이터를 담은 ‘작업(job)’ 메시지를 pgmq 큐(예: embedding_jobs)에 보낸다.22
  1. 비동기 워커(Asynchronous Worker):
  • pg_cron은 설정된 주기(예: 1분마다)에 따라 큐를 확인하는 PostgreSQL 함수(예: util.process_embeddings)를 실행한다.
  • 이 함수는 큐에 쌓여있는 작업들을 일정량의 배치(batch)로 묶어, pg_net을 사용하여 임베딩을 생성하는 Edge Function을 호출한다.
  • Edge Function은 전달받은 레코드 ID를 기반으로 데이터베이스에서 원본 콘텐츠를 조회하고, 임베딩을 생성한 후, 다시 해당 레코드의 임베딩 컬럼을 업데이트한다.22

장점:

  • 데이터 일관성 보장: 데이터가 변경될 때마다 임베딩 갱신 작업이 자동으로 큐에 등록되므로, 데이터와 임베딩 간의 동기화가 항상 보장된다. ‘데이터 드리프트’ 문제가 발생하지 않는다.23
  • 비동기 처리: 임베딩 생성은 시간이 소요될 수 있는 작업이다. 이 과정을 비동기적으로 백그라운드에서 처리함으로써, 데이터베이스의 기본 쓰기 작업(INSERT/UPDATE)을 차단하지 않아 애플리케이션의 응답성을 유지할 수 있다.23
  • 높은 안정성: 임베딩 생성 API 호출이 일시적으로 실패하더라도, 해당 작업은 큐에 그대로 남아있다가 다음 스케줄링 주기에 자동으로 재시도된다. 이를 통해 파이프라인의 안정성과 복원력(resilience)이 크게 향상된다.22

단점:

  • 초기 설정의 복잡성: 여러 확장 기능과 데이터베이스 함수, 트리거를 조합해야 하므로 다른 패턴에 비해 초기 설정이 복잡하다.
  • 플랫폼 의존성: pg_net, pgmq, pg_cron 등 Supabase 플랫폼에서 제공하는 특정 PostgreSQL 확장 기능에 대한 의존성이 발생한다.

이 세 가지 패턴의 선택은 단순한 기술적 선호의 문제가 아니다. 이는 애플리케이션의 데이터 수명 주기 관리 전략과 직결되는 핵심적인 아키텍처 설계 결정이다. 데이터가 거의 변경되지 않는 정적인 지식 기반(knowledge base)을 구축하는 경우, 초기 빌드 시점에 **패턴 1(수동)**을 사용하는 것이 효율적일 수 있다.21 사용자가 입력한 검색어처럼 일회성으로 임베딩이 필요하거나, 실시간 채팅 메시지처럼 즉각적인 임베딩 생성이 요구되는 시나리오에서는 **패턴 2(Edge Function)**가 적합하다. 마지막으로, 콘텐츠 관리 시스템(CMS), 블로그 플랫폼, 전자상거래 상품 정보와 같이 데이터가 지속적으로 생성되고 수정되는 동적인 시스템에서는 **패턴 3(자동화)**이 거의 필수적이다. 이 패턴을 채택하지 않으면 시간이 지남에 따라 검색 시스템의 신뢰도가 저하되는 기술 부채가 누적될 수밖에 없다. 따라서 개발자는 자신이 다루는 데이터의 생성, 수정, 삭제(CRUD) 패턴과 데이터의 최신성(freshness) 요구 수준을 면밀히 분석하여 가장 적합한 임베딩 관리 아키텍처를 선택해야 한다.

4. 벡터 유사도 검색의 수학적 원리

벡터 임베딩의 핵심 가치는 시맨틱 공간 내에서 벡터 간의 거리를 측정하여 원본 데이터의 유사도를 정량화하는 데 있다. pgvector는 이러한 유사도 측정을 위해 여러 가지 수학적 지표를 지원하며, 각 지표는 서로 다른 특성과 장단점을 가진다. 애플리케이션의 요구사항과 데이터의 특성에 맞는 올바른 거리 측정 방식을 선택하는 것은 검색 품질과 성능에 지대한 영향을 미친다.

4.1 L2 거리 (유클리드 거리, Euclidean Distance)

개념:

L2 거리는 우리가 일상적으로 인지하는 2차원 또는 3차원 공간에서의 ‘거리’ 개념을 다차원 벡터 공간으로 확장한 것이다. 두 벡터 A와 B가 가리키는 종점(end-point) 사이를 잇는 가장 짧은 직선 거리를 계산한다.8 이 측정 방식은 벡터의 각 차원별 값의 차이, 즉 벡터의 ‘크기(magnitude)’ 차이에 민감하게 반응한다.25

수학 공식:

두 n차원 벡터 A 와 B 에 대한 L2 거리는 피타고라스 정리를 일반화한 형태로, 각 차원별 차이의 제곱 합의 제곱근으로 계산된다.26
\delta_{L2}(\vec{A},\vec{B}) = \sqrt{\sum_{i=1}^{n} (A_i - B_i)^2}
pgvector 연산자:

pgvector에서는 <-> 연산자를 사용하여 L2 거리를 계산한다.14

해석 및 사용 사례:

L2 거리 값은 항상 0 이상이며, 값이 작을수록 두 벡터는 더 가깝고 유사하다고 판단한다. 벡터의 크기 자체가 중요한 정보를 담고 있는 경우에 유용하다. 예를 들어, 이미지의 색상 히스토그램을 벡터로 표현했을 때, 두 이미지의 전반적인 색상 분포 차이를 비교하는 데 적합하다. 또한, 특정 데이터 포인트가 정상 분포에서 얼마나 벗어났는지를 측정하는 이상 탐지(anomaly detection) 분야에서도 활용될 수 있다.8

4.2 코사인 유사도 (Cosine Similarity)

개념:

코사인 유사도는 두 벡터의 크기가 아닌, 그들이 가리키는 ’방향’의 유사성에 초점을 맞춘다. 이는 벡터의 길이를 1로 정규화(normalize)한 후, 두 벡터 사이의 각도(θ)의 코사인 값을 계산하는 것과 동일하다.8 따라서 문서의 길이나 이미지의 밝기 등 크기 요소에 영향을 받지 않고 순수한 내용적, 의미론적 유사성을 측정하는 데 매우 효과적이다.25

수학 공식:

두 벡터의 내적(dot product)을 각 벡터의 크기(norm 또는 magnitude)의 곱으로 나눈 값으로 정의된다.26
\text{Cosine Similarity}(\vec{A}, \vec{B}) = \cos(\theta) = \frac{\vec{A} \cdot \vec{B}}{\|\vec{A}\| \|\vec{B}\|} = \frac{\sum_{i=1}^{n} A_i B_i}{\sqrt{\sum_{i=1}^{n} A_i^2} \sqrt{\sum_{i=1}^{n} B_i^2}}
pgvector 연산자:

pgvector는 <=> 연산자를 제공하며, 이는 코사인 거리(Cosine Distance)를 계산한다. 코사인 거리는 1 - 코사인 유사도로 정의된다.14

해석 및 사용 사례:

코사인 유사도 값은 -1(완전히 반대 방향)부터 +1(완전히 같은 방향)까지의 범위를 가진다. 값이 1에 가까울수록 두 벡터의 방향이 일치하며, 의미적으로 더 유사하다고 해석한다. pgvector의 <=> 연산자는 ‘거리’ 개념이므로, 그 결과값이 0에 가까울수록(즉, 코사인 유사도가 1에 가까울수록) 더 유사하다. 텍스트 데이터의 시맨틱 검색에서 가장 널리 사용되는 지표이며, 문서의 길이에 상관없이 주제의 유사성을 비교하는 데 탁월하다.8

4.3 내적 (Inner Product / Dot Product)

개념:

내적은 한 벡터를 다른 벡터 위로 정사영(orthogonal projection)시켰을 때의 크기와 관련이 있다. 이는 두 벡터의 방향과 크기를 모두 고려하는 측정 방식이다.24 두 벡터가 같은 방향을 가리키고 크기가 클수록 내적 값은 커진다.

수학 공식:

각 차원별 요소를 곱한 값들의 총합으로 계산된다.25
\vec{A} \cdot \vec{B} = \sum_{i=1}^{n} A_i B_i

이는 \| A \| \| B \| \cos(\theta) 와 동일하다.

pgvector 연산자:

pgvector에서는 <#> 연산자를 사용한다. PostgreSQL의 인덱스 스캔은 오름차순(ASC) 정렬에 최적화되어 있으므로, pgvector는 최대 내적 값을 찾는 쿼리를 효율적으로 처리하기 위해 의도적으로 음수 내적(negative inner product)을 반환한다. 따라서 가장 유사한 항목을 찾기 위해서는 ORDER BY… ASC 구문을 사용해야 한다.18

해석 및 사용 사례:

<#> 연산자의 결과값이 작을수록(즉, 원래의 내적 값이 클수록) 두 벡터는 더 유사하다. 특히, 임베딩 벡터가 생성 시점에 이미 정규화(길이가 1인 단위 벡터)된 경우, 내적 계산은 코사인 유사도 계산과 수학적으로 동일해진다 ( ∥A∥=∥B∥=1 이므로 A⋅B=cos(θ) ). 이 경우, 분모 계산이 생략되므로 세 가지 연산자 중 가장 계산 속도가 빠르다. OpenAI의 text-embedding-ada-002와 같은 많은 최신 임베딩 모델들은 정규화된 벡터를 출력하므로, 이러한 모델과 함께 사용할 때 내적은 성능상 가장 유리한 선택이 될 수 있다.14

4.4 거리 측정 지표 비교 분석

애플리케이션에 적합한 거리 측정 지표를 선택하는 것은 단순한 공식의 문제가 아니라, 데이터의 특성과 성능 요구사항을 모두 고려해야 하는 전략적 결정이다. 아래 표는 세 가지 주요 지표의 핵심적인 차이점을 요약하여 의사결정을 돕는다.

특성L2 거리 (Euclidean)코사인 유사도 (Cosine Similarity)내적 (Inner Product)
pgvector 연산자<-><=> (코사인 거리)<#> (음수 내적)
측정 대상벡터 종점 간의 직선 거리 (크기 차이에 민감)벡터 간의 각도 (방향성, 크기와 무관)한 벡터를 다른 벡터에 투영한 크기 (방향과 크기 모두 고려)
주요 사용 사례이미지 유사도 검색(색상, 질감 등), 이상 탐지시맨틱 텍스트 검색, 문서 분류, 추천 시스템추천 시스템, 벡터가 정규화되었을 때의 고속 시맨틱 검색
값의 의미0에 가까울수록 유사연산자(<=>) 결과가 0에 가까울수록 유사연산자(<#>_ 결과가 작을수록(원래 내적은 클수록) 유사
성능 및 정규화계산 비용이 상대적으로 높음정규화 과정이 포함되어 계산 비용 발생벡터가 정규화( ∥v∥=1 )된 경우, 코사인 유사도와 결과가 동일하며 연산 속도가 가장 빠름

이 표에서 가장 주목해야 할 점은 ‘성능 및 정규화’ 항목이다. 시맨틱 텍스트 검색과 같이 벡터의 ’방향’이 중요한 대부분의 경우, 코사인 유사도가 개념적으로 가장 적합하다. 그러나 만약 사용하는 임베딩 모델이 정규화된 벡터를 출력한다면, 수학적으로 동일한 결과를 내면서도 연산 비용이 가장 저렴한 ’내적’을 사용하는 것이 성능 최적화의 핵심 전략이 된다. 따라서 개발자는 자신이 사용하는 임베딩 모델의 출력 벡터가 정규화되었는지 확인하고, 그에 따라 가장 효율적인 거리 측정 연산자를 선택해야 한다.

5. pgvector 성능 최적화: 인덱싱 전략 심층 비교

수십만 개 이상의 벡터를 다루는 실제 애플리케이션 환경에서, 모든 벡터를 순차적으로 비교하여 유사도를 계산하는 방식(순차 스캔, Sequential Scan)은 용납할 수 없는 성능 저하를 초래한다. 이는 정확한 최근접 이웃(Exact Nearest Neighbor, ENN) 탐색 방식으로, 완벽한 정확도를 보장하지만 데이터 양에 비례하여 검색 시간이 선형적으로 증가하는 O(N)의 시간 복잡도를 가진다. 이러한 성능 한계를 극복하기 위해 pgvector는 인덱스를 활용한 근사 최근접 이웃(Approximate Nearest Neighbor, ANN) 탐색을 지원한다.6 ANN 인덱스는 약간의 정확도(recall)를 희생하는 대신, 검색 속도를 수십에서 수백 배까지 극적으로 향상시키는 것을 목표로 한다.29

Supabase의 pgvector는 현재 두 가지 주요 ANN 인덱스 알고리즘인 IVFFlat과 HNSW를 지원한다.

5.1 IVFFlat (Inverted File with Flat Compression) 인덱스

작동 원리:

IVFFlat은 전체 벡터 공간을 여러 개의 작은 구역으로 분할하고, 검색 시에는 쿼리 벡터와 관련된 일부 구역만 탐색하여 계산량을 줄이는 ‘분할 정복(divide and conquer)’ 전략을 사용한다.30

  1. 훈련 (Training) / 클러스터링 (Clustering): 인덱스를 생성할 때, K-평균(K-means) 클러스터링 알고리즘을 사용하여 전체 데이터 벡터를 사용자가 지정한 lists 개수만큼의 클러스터(군집)로 나눈다. 각 클러스터의 중심점을 ’중심점(centroid)’이라고 부른다. 이 과정 때문에 IVFFlat 인덱스는 생성 시점에 테이블에 일정량의 대표 데이터가 존재해야 한다.29
  2. 인덱싱 (Indexing): 각 데이터 벡터를 자신과 가장 가까운 중심점에 할당한다. 이를 통해 ‘중심점 ID -> [해당 클러스터에 속한 벡터들의 목록]’ 형태로 구성된 역파일(inverted file) 구조를 만든다. 이것이 ’Inverted File’이라는 이름의 유래다.31
  3. 검색 (Querying): 새로운 쿼리 벡터가 주어지면, 전체 데이터 벡터와 비교하는 대신 먼저 모든 중심점과 거리를 계산한다. 그 후, 쿼리 벡터와 가장 가까운 probes 개수의 중심점을 선택하고, 해당 중심점들이 대표하는 클러스터(리스트)에 속한 벡터들하고만 정밀한 거리 계산을 수행하여 최종 결과를 도출한다.34

주요 파라미터:

  • lists: 생성할 클러스터의 총 개수. 이 값이 클수록 각 클러스터의 크기가 작아져 검색 속도는 빨라지지만, 인접한 클러스터에 있을 수 있는 실제 최근접 이웃을 놓칠 가능성이 커져 정확도(recall)는 낮아질 수 있다. 데이터셋 크기에 따라 rows / 1000 (1백만 건 이하) 또는 sqrt(rows) (1백만 건 이상)로 설정하는 것이 일반적인 출발점이다.34
  • probes: 쿼리 시 탐색할 클러스터의 개수. 이 값을 높이면 더 많은 후보군을 탐색하므로 정확도는 향상되지만 검색 속도는 느려진다. sqrt(lists) 값을 시작점으로 튜닝하는 것이 권장된다.34

장단점:

  • 장점: HNSW에 비해 인덱스 빌드 시간이 빠르고 메모리 사용량이 적어 리소스가 제한적인 환경에 유리하다.18
  • 단점: HNSW 대비 속도-정확도 트레이드오프 측면에서 성능이 낮다. 데이터 분포가 크게 변경되면 클러스터의 효율성이 떨어지므로 주기적인 인덱스 재빌드가 권장된다.30

5.2 HNSW (Hierarchical Navigable Small World) 인덱스

작동 원리:

HNSW는 소셜 네트워크의 ’6단계 분리 법칙’과 유사한 ‘작은 세상 네트워크(Small World Network)’ 개념과 스킵 리스트(skip list) 자료 구조에서 영감을 받은 정교한 그래프 기반 알고리즘이다.38

  1. 계층적 그래프 구조: HNSW 인덱스는 여러 계층(layer)으로 구성된 그래프를 구축한다. 최상위 계층(layer)은 가장 적은 수의 노드(벡터)를 포함하며, 노드 간의 거리가 먼 ’긴 연결(long-range link)’을 가진다. 이는 전체 벡터 공간을 빠르게 탐색하는 고속도로 역할을 한다. 하위 계층으로 내려갈수록 노드의 수가 기하급수적으로 많아지고, 노드 간의 연결은 더 촘촘하고 짧아져(short-range link) 정밀한 탐색을 가능하게 한다.41
  2. 탐색 과정: 검색은 항상 가장 희소한 최상위 계층의 미리 정의된 진입점(entry point)에서 시작된다. 현재 위치한 노드의 이웃들 중에서 쿼리 벡터와 가장 가까운 노드를 탐욕적(greedy)으로 찾아 이동한다. 이 과정을 반복하다가 더 이상 가까운 이웃을 찾을 수 없는 지역 최적점(local minimum)에 도달하면, 한 단계 아래 계층으로 이동하여 방금 찾은 노드를 새로운 진입점으로 삼아 탐색을 계속한다. 이 과정을 최하위 계층(모든 데이터 노드가 포함된 layer 0)까지 반복하여 최종적인 근사 최근접 이웃을 찾는다.38

주요 파라미터:

  • m: 그래프의 각 계층에서 하나의 노드가 가질 수 있는 최대 이웃(연결)의 수. 이 값이 클수록 그래프가 더 촘촘해져 탐색 경로가 최적화되므로 정확도는 높아지지만, 인덱스 크기와 빌드 시간이 증가한다. 기본값은 16이다.36
  • ef_construction: 인덱스를 빌드하는 과정에서 각 노드의 이웃을 찾기 위해 동적으로 유지하는 후보 리스트의 크기. 이 값이 클수록 더 좋은 품질의 그래프가 생성되어 잠재적으로 정확도가 향상되지만, 빌드 시간이 급격히 늘어난다. 기본값은 64이다.36
  • ef_search: 쿼리를 수행할 때 탐색을 위해 유지하는 후보 리스트의 크기. IVFFlat의 probes와 유사한 역할을 하며, 이 값을 높이면 정확도는 향상되지만 검색 속도는 느려진다.36

장단점:

  • 장점: IVFFlat에 비해 월등한 쿼리 성능(더 나은 속도-정확도 균형)을 제공한다.18 데이터가 없는 빈 테이블에서도 인덱스 생성이 가능하며, 데이터의 추가 및 삭제에 대해 상대적으로 강건하여 동적인 데이터 환경에 더 적합하다.29
  • 단점: 인덱스 빌드 시간이 IVFFlat보다 훨씬 길고, 더 많은 메모리를 사용한다.18

5.3 IVFFlat vs. HNSW 인덱스 전략 비교

두 인덱싱 전략은 명확한 트레이드오프 관계를 가지므로, 애플리케이션의 특성과 요구사항에 따라 신중하게 선택해야 한다. 아래 표는 두 인덱스의 핵심적인 차이점을 요약하여 합리적인 의사결정을 지원한다.

구분IVFFlatHNSW
핵심 알고리즘K-평균 클러스터링 기반 역파일 인덱스다계층 근접성 그래프
쿼리 성능중간 (Moderate)매우 빠름 (Very Fast)
인덱스 빌드 시간빠름 (Fast)느림 (Slower)
메모리 사용량낮음 (Lower)높음 (Higher)
데이터 요구사항인덱스 생성 시 데이터 필요 (클러스터링 때문)빈 테이블에서도 생성 가능
데이터 변경 대응데이터 분포 변경 시 재빌드 권장추가/삭제에 상대적으로 강건함
주요 빌드 파라미터lists (클러스터 수)m (최대 연결 수), ef_construction (빌드 후보 리스트)
주요 쿼리 파라미터probes (탐색할 클러스터 수)ef_search (검색 후보 리스트)
적합한 사용 사례- 리소스가 제한적인 환경 - 데이터셋이 비교적 정적일 때 - 빠른 초기 인덱싱이 중요할 때- 실시간, 낮은 지연 시간(low-latency)의 쿼리 응답이 중요할 때 - 데이터가 자주 추가/변경되는 동적 환경 - 최고의 정확도-속도 균형이 필요할 때
참고 자료1818

결론적으로, 빠른 초기 구축과 낮은 리소스 사용이 중요하다면 IVFFlat이 합리적인 선택일 수 있다. 그러나 대부분의 현대적인 AI 애플리케이션에서 요구하는 실시간에 가까운 낮은 지연 시간과 높은 정확도를 동시에 만족시키기 위해서는, 더 많은 빌드 시간과 메모리를 투자하더라도 HNSW가 월등한 성능을 제공한다. 특히 데이터가 지속적으로 변경되는 환경에서는 HNSW의 강건함이 더욱 빛을 발한다.

6. 경쟁 솔루션과의 비교 분석

Supabase와 pgvector의 조합이 제공하는 가치를 객관적으로 평가하기 위해서는, 시장에 존재하는 다른 벡터 데이터베이스 솔루션, 특히 벡터 검색에 특화된 전용(specialized) 데이터베이스와의 비교가 필수적이다. 본 섹션에서는 대표적인 경쟁 솔루션인 Pinecone과 Weaviate를 대상으로 아키텍처, 성능, 비용, 데이터 관리 등 다각적인 측면에서 심층 비교 분석을 수행한다.

6.1 Supabase/pgvector vs. Pinecone

아키텍처 철학: 통합(Unified) vs. 전용(Specialized)

가장 근본적인 차이는 아키텍처 철학에 있다. Supabase/pgvector는 기존의 강력한 관계형 데이터베이스인 PostgreSQL에 벡터 처리 기능을 ’통합’하는 접근 방식을 취한다. 이를 통해 개발자는 단일 데이터베이스 내에서 정형 데이터(사용자 정보, 상품 메타데이터 등)와 비정형 데이터(임베딩 벡터)를 함께 관리하고, SQL을 통해 이들을 자유롭게 조인(JOIN)할 수 있다.44 반면, Pinecone은 오직 벡터 저장 및 검색 기능에만 초점을 맞춘 ‘전용’ 완전 관리형 서비스(fully managed service)이다.44 이는 필연적으로 애플리케이션 아키텍처 내에 별도의 데이터 저장소를 추가하게 된다.

성능: QPS(Throughput) vs. Latency(지연 시간)

성능 비교는 어떤 지표를 중시하느냐에 따라 해석이 달라질 수 있다. Supabase가 수행한 벤치마크에 따르면, 동일한 월간 비용의 클라우드 인스턴스를 기준으로 pgvector의 HNSW 인덱스가 Pinecone의 모든 Pod 타입(s1, p1, p2)보다 더 높은 QPS(Queries Per Second, 초당 처리 쿼리 수)와 더 나은 정확도(accuracy@10)를 기록했다.11 이는

pgvector가 단위 비용 당 더 많은 요청을 처리할 수 있는 잠재력을 가지고 있음을 시사한다.

그러나 일부 실제 사용자 경험에 따르면, 개별 쿼리의 응답 시간, 즉 지연 시간(latency) 측면에서는 Pinecone이 더 우수하고 예측 가능한 성능을 제공한다고 보고된다. 한 사례에서는 Supabase에서 평균 150-200ms가 소요되던 쿼리가 Pinecone으로 이전 후 40-80ms로 단축되었다고 한다.46 이는 Pinecone의 아키텍처가 벡터 검색이라는 특정 워크로드에 고도로 최적화되어 있기 때문으로 분석된다.

비용 및 확장성(Scalability)

pgvector는 오픈소스 확장 기능이므로 직접적인 라이선스 비용은 없다. 비용은 기반이 되는 PostgreSQL 인스턴스의 사양(CPU, RAM, 스토리지)에 따라 결정된다. 이는 초기 비용이 낮고 예측 가능하다는 장점이 있지만, 수천만 건 이상의 대규모 데이터셋으로 확장할 경우, 인덱스를 메모리에 상주시키기 위한 고사양 인스턴스가 필요하게 되며, 샤딩(sharding)과 같은 수평적 확장을 위해서는 사용자의 깊은 데이터베이스 전문 지식과 운영 노력이 요구된다.44

Pinecone은 사용량 기반 과금 모델을 채택한 관리형 서비스로, 사용자는 인프라 관리에 대한 부담 없이 손쉽게 확장할 수 있다.44 그러나 이는 벤더 종속성(vendor lock-in)을 초래할 수 있으며, 대규모 워크로드에서는

pgvector를 자체 호스팅하는 것보다 비용이 더 높아질 수 있다.11 Pinecone의 Standard 플랜은 월 최소 $50의 사용료가 부과된다.48

데이터 관리 및 유연성

데이터 관리 측면에서는 Supabase/pgvector가 압도적인 우위를 점한다. PostgreSQL의 성숙한 생태계가 제공하는 모든 기능, 즉 ACID 트랜잭션을 통한 데이터 일관성 보장, 강력한 SQL 쿼리 언어, 행 수준 보안(Row-Level Security, RLS), 상세한 사용자 역할 관리, 자동 백업 및 특정 시점 복구(PITR) 등을 그대로 활용할 수 있다.11

반면, Pinecone은 API를 통해서만 데이터에 접근할 수 있으며, 이로 인해 몇 가지 제약이 발생한다. 가장 큰 문제는 주 데이터 저장소(예: PostgreSQL)와 Pinecone 간의 데이터 동기화를 애플리케이션 레벨에서 직접 관리해야 한다는 점이다. 이 과정에서 동기화가 실패하면 데이터 불일치가 발생할 수 있다.11 또한, 벡터당 저장할 수 있는 메타데이터의 크기가 40KB로 제한되어 있어, 이보다 큰 메타데이터가 필요한 경우 주 데이터베이스에 추가적인 조회를 해야 하는 번거로움이 있다.11

6.2 Supabase/pgvector vs. Weaviate

주요 특징 및 지향점

Weaviate는 오픈소스 기반의 전용 벡터 데이터베이스로, 단순한 벡터 검색을 넘어 AI 애플리케이션 개발을 위한 통합적인 기능을 제공하는 것을 목표로 한다. 벡터와 원본 데이터를 ‘객체(object)’ 단위로 함께 저장하고, GraphQL API를 통해 유연한 데이터 조작을 지원하며, 다양한 임베딩 모델을 데이터베이스 내에 모듈 형태로 내장하여 데이터 수집 시 자동으로 임베딩을 생성하는 기능을 제공하는 것이 특징이다.50

이에 반해 Supabase/pgvector는 PostgreSQL이라는 범용 데이터베이스의 확장성을 기반으로 벡터 기능을 제공한다. 이는 특정 기능에 특화되기보다는, 개발자가 PostgreSQL의 광범위한 생태계와 도구를 활용하여 자신만의 솔루션을 구축할 수 있는 높은 유연성을 제공하는 데 초점을 맞춘다.

사용 편의성 및 생태계

사용자 리뷰에 따르면, Supabase는 직관적인 대시보드와 잘 정리된 문서 덕분에 초기 설정의 용이성과 지원 품질 측면에서 Weaviate보다 높은 평가를 받는 경향이 있다.50 Weaviate는 GraphQL과 같은 독자적인 개념에 익숙해져야 하는 학습 곡선이 존재할 수 있다.

기능적 측면에서 Weaviate는 pgvector(최대 2,000 차원)보다 훨씬 높은 차원의 벡터(최대 65,535 차원)를 지원하므로, 매우 고차원의 임베딩을 사용하는 특정 연구나 애플리케이션에 더 적합할 수 있다.52

성능

일반적으로 ANN-Benchmarks와 같은 객관적인 벤치마크에서는 Weaviate와 같은 전용 벡터 데이터베이스가 pgvector에 비해 더 높은 처리량(throughput)과 낮은 지연 시간을 보이는 경향이 있다.52 이는 전용 데이터베이스가 벡터 연산에 최적화된 스토리지 엔진과 쿼리 실행 계획을 가지고 있기 때문이다. 그러나 이러한 성능 차이는 워크로드의 특성, 데이터셋의 크기, 하드웨어 사양, 그리고 pgvector의 인덱스 튜닝 수준에 따라 크게 달라질 수 있다.

6.3 벡터 데이터베이스 솔루션 비교 요약

각 솔루션은 뚜렷한 아키텍처적 철학을 바탕으로 서로 다른 강점과 약점을 지닌다. 따라서 ‘최고의’ 솔루션은 존재하지 않으며, 프로젝트의 요구사항과 제약 조건에 가장 잘 ‘부합하는’ 솔루션이 존재할 뿐이다. 아래 표는 세 가지 솔루션의 핵심적인 특징을 비교하여 전략적인 의사결정을 돕는다.

구분Supabase / pgvectorPineconeWeaviate
아키텍처통합형: PostgreSQL 확장 기능전용: 완전 관리형 벡터 DB전용: 오픈소스 기반 벡터 DB
핵심 장점- 데이터 관리 통합 (No Silo) - PostgreSQL 생태계 활용 - 강력한 메타데이터 필터링- 낮은 쿼리 지연 시간 - 예측 가능한 성능 - 운영 부담 최소화- 강력한 시맨틱/하이브리드 검색 - GraphQL API - 내장 임베딩 모듈
핵심 단점- 대규모 확장 시 전문성 요구 - 전용 DB 대비 높은 지연 시간 가능성- 주 DB와 데이터 동기화 문제 - 메타데이터 제약 (40KB) - 벤더 종속성(Vendor Lock-in)- 상대적으로 복잡한 설정 - pgvector 대비 높은 리소스 요구
성능 (QPS)동일 비용 하드웨어에서 높음 (벤치마크 기준)선형적 확장 가능벤치마크에서 높은 처리량 보임
성능 (Latency)SQL 튜닝에 따라 가변적낮고 안정적빠름 (빠른 쿼리 시간 보고됨)
비용 모델PostgreSQL 인스턴스 비용 + α사용량 기반 (최소 요금 존재)오픈소스 (자체 호스팅) 또는 사용량 기반 (관리형)
적합한 사용 사례- 기존 PostgreSQL 사용자가 벡터 기능 추가 시 - 관계형 데이터와 벡터 검색을 결합해야 할 때 - 비용 효율적인 중소규모 프로젝트- 벡터 검색이 애플리케이션의 핵심일 때 - 초저지연(ultra-low latency)이 필수적일 때 - 인프라 운영 부담을 피하고 싶을 때- 복잡한 시맨틱 검색 요구사항 - 데이터와 벡터를 객체로 함께 관리 - 유연한 데이터 모델링이 필요할 때
참고 자료111150

7. 실용적 고려사항 및 권장 사항

7.1 임베딩 모델 선택 가이드

성공적인 벡터 검색 시스템 구축의 첫 단추는 사용 사례에 적합한 임베딩 모델을 선택하는 것이다. 모델의 선택은 검색 품질, 시스템 성능, 그리고 비용에 직접적인 영향을 미친다.

MTEB 리더보드 활용:

다양한 텍스트 임베딩 모델의 성능을 객관적으로 비교하기 위한 좋은 출발점은 허깅페이스(Hugging Face)에서 호스팅하는 MTEB(Massive Text Embedding Benchmark) 리더보드이다.54 MTEB는 분류, 클러스터링, 검색 등 다양한 작업에 대한 모델 성능을 평가하는데, 특히 벡터 검색 및 RAG(Retrieval-Augmented Generation) 사용 사례에서는 ‘Retrieval Average’ 점수를 핵심 지표로 삼는 것이 유용하다.56

주요 고려사항:

  1. 차원 수 (Dimensions): 벡터의 차원 수는 성능과 비용에 직접적인 영향을 미친다. 낮은 차원의 벡터는 저장 공간을 적게 차지하고 유사도 계산 속도가 빠르다는 장점이 있다.54 반면, 높은 차원의 벡터는 더 많은 의미 정보를 포착할 수 있지만 더 많은 계산 자원을 필요로 한다.19 따라서 애플리케이션의 요구 정확도와 성능 제약 사이의 균형을 맞추는 것이 중요하다.
  2. 모델 크기 (Model Size): 모델의 크기는 자체 호스팅(self-hosting) 또는 Supabase Edge Functions와 같이 제한된 환경에서 모델을 실행할 수 있는지 여부를 결정한다. MTEB 리더보드 상위권에 있는 많은 최신 모델들은 소비자용 하드웨어에서도 충분히 실행 가능할 정도로 크기가 작아졌다.55
  3. 도메인 특수성 (Domain Specificity): 법률, 의료, 금융, 사이버 보안과 같은 특정 전문 분야의 문서를 다룰 경우, 일반적인 텍스트로 학습된 범용 모델보다 해당 도메인의 데이터로 미세 조정(fine-tuning)되거나 사전 학습된 모델이 훨씬 더 나은 성능을 보인다.19
  4. 비용 및 라이선스: OpenAI의 ada-002나 Cohere의 모델과 같은 상용 API는 사용이 간편하고 높은 성능을 제공하지만 사용량에 따라 비용이 발생한다. 반면, E5gte-small과 같은 오픈소스 모델은 비용 없이 사용할 수 있지만, 모델을 직접 호스팅하고 관리해야 하는 부담이 따를 수 있다. 각 모델의 라이선스 정책을 반드시 확인해야 한다.19
  5. 자체 데이터셋 평가: MTEB 리더보드는 훌륭한 가이드라인을 제공하지만, 최종적인 선택은 실제 사용할 데이터셋에 대한 평가를 통해 이루어져야 한다. 특정 모델이 특정 데이터의 뉘앙스와 문맥을 얼마나 잘 포착하는지는 직접 테스트를 통해 검증하는 것이 가장 확실하다.54

7.2 pgvector 쿼리 최적화 모범 사례

pgvector의 잠재력을 최대한 활용하기 위해서는 신중한 쿼리 작성과 데이터베이스 튜닝이 필수적이다.

  1. EXPLAIN ANALYZE 활용: 모든 성능 튜닝의 시작은 EXPLAIN ANALYZE 명령어를 통해 PostgreSQL의 쿼리 실행 계획을 분석하는 것이다. 이 명령어를 사용하면 작성한 쿼리가 실제로 인덱스를 사용하고 있는지(Index Scan), 아니면 비효율적인 순차 스캔(Sequential Scan)을 수행하고 있는지, 각 단계에서 소요되는 시간은 얼마인지 등을 명확하게 확인할 수 있다. 이를 통해 성능 병목 구간을 식별하고 최적화를 진행해야 한다.57
  2. 인덱스 및 파라미터 튜닝: 앞서 V장에서 논의한 바와 같이, 데이터셋의 크기, 데이터 분포, 쿼리 패턴(정확도 vs. 속도)을 고려하여 IVFFlat 또는 HNSW 인덱스를 선택하고, 관련 파라미터(lists, probes, m, ef_construction, ef_search)를 신중하게 조정해야 한다. 이는 시행착오를 통한 반복적인 튜닝 과정이 필요할 수 있다.57
  3. PostgreSQL 설정 최적화: pgvector의 성능은 PostgreSQL 자체의 설정값에 크게 의존한다. 특히 메모리 관련 파라미터가 중요하다.
  • shared_buffers: PostgreSQL이 데이터 캐싱에 사용하는 메모리 양을 결정한다. 일반적으로 시스템 전체 RAM의 25-40%로 설정하는 것이 권장된다.57
  • work_mem: 정렬(sorting), 조인(join) 등 복잡한 쿼리 작업에 사용되는 메모리 양을 결정한다. 벡터 쿼리는 대규모 정렬 작업을 포함하므로 이 값을 적절히 늘리면 성능 향상에 도움이 될 수 있다.57
  • maintenance_work_mem: 인덱스 생성, VACUUM 등 유지보수 작업에 사용되는 메모리다. 특히 대규모 데이터에 대한 HNSW 인덱스 생성 시 이 값을 충분히 높여주면 빌드 시간을 크게 단축할 수 있다.58
  1. 데이터 로딩 순서: 대량의 데이터를 테이블에 삽입할 때는, 먼저 데이터를 모두 삽입한 후에 인덱스를 생성하는 것이 훨씬 효율적이다. 빈 테이블에 인덱스를 먼저 생성하고 데이터를 하나씩 삽입하면 인덱스 구조를 계속해서 재조정해야 하므로 성능이 저하된다.58
  2. 정기적인 유지보수: PostgreSQL은 VACUUMANALYZE 명령어를 통해 테이블의 불필요한 공간을 정리하고 통계 정보를 최신 상태로 유지한다. 데이터의 추가/삭제가 빈번한 테이블에 대해 이러한 유지보수 작업을 정기적으로 수행하는 것은 쿼리 플래너가 최적의 실행 계획을 수립하는 데 필수적이다.57

7.3 결론: 사용 사례 기반의 아키텍처 선택 전략

Supabase와 pgvector는 강력하고 유연한 벡터 데이터베이스 솔루션을 제공하지만, 모든 시나리오에 대한 만병통치약은 아니다. 최종적인 아키텍처 선택은 프로젝트의 구체적인 요구사항과 제약 조건에 따라 신중하게 이루어져야 한다.

  • 프로토타입 및 중소규모 애플리케이션: Supabase/pgvector는 이상적인 선택이다. 기존에 익숙한 PostgreSQL 인프라와 SQL을 그대로 활용하면서 벡터 검색 기능을 빠르게 구현할 수 있다. 개발 속도를 높이고 초기 인프라 비용을 최소화하는 데 매우 효과적이다.
  • 관계형 데이터와 벡터 검색이 밀접하게 결합된 경우: 예를 들어, 특정 사용자 그룹에 속하고(WHERE user_group = 'premium'), 특정 기간 내에 작성되었으며(WHERE created_at > '2024-01-01'), 특정 쿼리와 의미적으로 유사한 문서를 찾는 복잡한 필터링이 필요한 경우, Supabase/pgvector는 단일 SQL 쿼리 내에서 이 모든 조건을 처리할 수 있는 강력한 이점을 제공한다. 이는 데이터 일관성을 보장하고 애플리케이션 로직을 단순화한다.
  • 벡터 검색이 핵심이며 초저지연이 요구되는 대규모 애플리케이션: 애플리케이션의 핵심 가치가 벡터 검색 자체에 있고, 수천만 건 이상의 데이터에 대해 100ms 이하의 안정적인 응답 시간이 비즈니스적으로 필수적인 경우, Pinecone과 같은 전용 벡터 데이터베이스를 고려하는 것이 합리적일 수 있다. 이는 더 높은 비용과 아키텍처 복잡성을 감수하더라도, 예측 가능하고 최적화된 성능을 확보하기 위한 전략적 선택이다.

궁극적으로 pgvector의 등장은 과거 데이터베이스 시장에서 반복되었던 패턴을 연상시킨다. 과거 JSON 문서 처리를 위해 MongoDB가, 시계열 데이터 처리를 위해 InfluxDB가 부상했지만, 결국 PostgreSQL은 JSONB 타입과 TimescaleDB 확장 기능 등을 통해 해당 워크로드의 상당 부분을 성공적으로 흡수했다.45 개발자들은 종종 아키텍처의 단순화, 데이터 관리의 통합, 그리고 성숙하고 방대한 생태계가 주는 이점 때문에, 특정 영역에서 최고의 성능을 내는 전용 솔루션 대신 ‘충분히 좋은(good enough)’ 통합 솔루션으로 회귀하는 경향을 보인다.

pgvector가 HNSW 인덱스를 도입하며 성능 격차를 빠르게 줄여나가고 있는 현재 상황은, 이러한 패턴이 벡터 데이터베이스 영역에서도 재현될 수 있음을 강력하게 시사한다.11 따라서 Supabase/pgvector를 선택하는 것은 단순히 현재의 성능 벤치마크를 넘어, PostgreSQL이라는 거대한 기술 생태계의 지속적인 발전과 안정성에 투자하는 장기적인 관점의 전략적 결정으로 평가될 수 있다.

8. 참고 자료

  1. What are Vector Embeddings? | A Comprehensive Vector Embeddings Guide - Elastic, https://www.elastic.co/what-is/vector-embedding
  2. What is Vector Embedding? | IBM, https://www.ibm.com/think/topics/vector-embedding
  3. What Are Vector Embeddings? An Intuitive Explanation - DataCamp, https://www.datacamp.com/blog/vector-embedding
  4. What is Embeddings in Machine Learning? - AWS, https://aws.amazon.com/what-is/embeddings-in-machine-learning/
  5. What Are Vector Embeddings? Models & More Explained - Couchbase, https://www.couchbase.com/blog/what-are-vector-embeddings/
  6. Storing OpenAI embeddings in Postgres with pgvector - Supabase, https://supabase.com/blog/openai-embeddings-postgres-vector
  7. What are vector embeddings? A complete guide [2025] - Meilisearch, https://www.meilisearch.com/blog/what-are-vector-embeddings
  8. pgvector on Heroku Postgres, https://devcenter.heroku.com/articles/pgvector-heroku-postgres
  9. AI & Vectors | Supabase Docs, https://supabase.com/docs/guides/ai
  10. The Postgres Vector database and AI Toolkit - Supabase, https://supabase.com/modules/vector
  11. Why we replaced Pinecone with PGVector - Confident AI, https://www.confident-ai.com/blog/why-we-replaced-pinecone-with-pgvector
  12. Vector Databases vs. PostgreSQL with pg_vector for RAG Setups - DEV Community, https://dev.to/simplr_sh/vector-databases-vs-postgresql-with-pgvector-for-rag-setups-1lg2
  13. PostgreSQL as a Vector Database: A Pgvector Tutorial - TigerData, https://www.tigerdata.com/blog/postgresql-as-a-vector-database-using-pgvector
  14. Vector columns | Supabase Docs, https://supabase.com/docs/guides/ai/vector-columns
  15. pgvector: Embeddings and vector similarity | Supabase Docs, https://supabase.com/docs/guides/database/extensions/pgvector
  16. How to enable pgvector in Supabase - Nesin.io, https://nesin.io/blog/enable-pgvector-supabase
  17. Generate Embeddings | Supabase Docs, https://supabase.com/docs/guides/ai/quickstarts/generate-text-embeddings
  18. pgvector/pgvector: Open-source vector similarity search for Postgres - GitHub, https://github.com/pgvector/pgvector
  19. Selecting Embedding Models - Cisco, https://sec.cloudapps.cisco.com/security/center/resources/selecting-embedding-models
  20. The pgvector extension - Neon Docs, https://neon.com/docs/extensions/pgvector
  21. Vector search with Next.js and OpenAI | Supabase Docs, https://supabase.com/docs/guides/ai/examples/nextjs-vector-search
  22. Automatic embeddings | Supabase Docs, https://supabase.com/docs/guides/ai/automatic-embeddings
  23. Automatic Embeddings in Postgres - Supabase, https://supabase.com/blog/automatic-embeddings
  24. medium.com, https://medium.com/@zilliz_learn/similarity-metrics-for-vector-search-62ccda6cfdd8#:~:text=The%20L2%20or%20Euclidean%20metric,one%20vector%20onto%20the%20other.
  25. Similarity Metrics for Vector Search - Zilliz blog, https://zilliz.com/blog/similarity-metrics-for-vector-search
  26. Vector similarity techniques and scoring - Elasticsearch Labs, https://www.elastic.co/search-labs/blog/vector-similarity-techniques-and-scoring
  27. Cosine similarity - Wikipedia, https://en.wikipedia.org/wiki/Cosine_similarity
  28. Similarity Metrics Milvus v2.4.x documentation, https://milvus.io/docs/v2.4.x/metric.md
  29. An early look at HNSW performance with pgvector | Jonathan Katz, https://jkatz05.com/post/postgres/pgvector-hnsw-performance/
  30. Nearest Neighbor Indexes: What Are IVFFlat Indexes in Pgvector and How Do They Work, https://www.tigerdata.com/blog/nearest-neighbor-indexes-what-are-ivfflat-indexes-in-pgvector-and-how-do-they-work
  31. IVFFlat indexes | Supabase Docs, https://supabase.com/docs/guides/ai/vector-indexes/ivf-indexes
  32. IVFFlat Index - Write You a Vector Database, https://skyzh.github.io/write-you-a-vector-db/cpp-05-ivfflat.html
  33. Understanding PostgreSQL pgvector Indexing with IVFFlat | by Maurício Maia | Medium, https://medium.com/@mauricio/optimizing-ivfflat-indexing-with-pgvector-in-postgresql-755d142e54f5
  34. How to optimize performance when using pgvector - Azure Cosmos DB for PostgreSQL, https://learn.microsoft.com/en-us/azure/cosmos-db/postgresql/howto-optimize-performance-pgvector
  35. Accelerated Vector Search: Approximating with NVIDIA cuVS Inverted Index, https://developer.nvidia.com/blog/accelerated-vector-search-approximating-with-nvidia-cuvs-ivf-flat/
  36. Use pgvector for Vector Similarity Search | Apache Cloudberry (Incubating), https://cloudberry.apache.org/docs/advanced-analytics/pgvector-search/
  37. Vector Search Demystified: A Guide to pgvector, IVFFlat, and HNSW - Nocodo AI, https://www.nocodo.ai/blog/vector-search-demystified-guide-to-pgvector-ivfflat-and-hnsw
  38. Optimize generative AI applications with pgvector indexing: A deep dive into IVFFlat and HNSW techniques | AWS Database Blog, https://aws.amazon.com/blogs/database/optimize-generative-ai-applications-with-pgvector-indexing-a-deep-dive-into-ivfflat-and-hnsw-techniques/
  39. What is a Hierarchical Navigable Small World - MongoDB, https://www.mongodb.com/resources/basics/hierarchical-navigable-small-world
  40. Similarity Search, Part 4: Hierarchical Navigable Small World (HNSW), https://towardsdatascience.com/similarity-search-part-4-hierarchical-navigable-small-world-hnsw-2aad4fe87d37/
  41. PGVector: HNSW vs IVFFlat — A Comprehensive Study | by BavalpreetSinghh | Medium, https://medium.com/@bavalpreetsinghh/pgvector-hnsw-vs-ivfflat-a-comprehensive-study-21ce0aaab931
  42. The Hierarchial Navigable Small Worlds (HNSW) Algorithm | Lantern Blog, https://lantern.dev/blog/hnsw
  43. HNSW Indexes with Postgres and pgvector | Crunchy Data Blog, https://www.crunchydata.com/blog/hnsw-indexes-with-postgres-and-pgvector
  44. Pgvector vs Pinecone: Choosing the Right Vector Database - Openxcell, https://www.openxcell.com/blog/pgvector-vs-pinecone/
  45. pgvector vs Pinecone: cost and performance - Supabase, https://supabase.com/blog/pgvector-vs-pinecone
  46. Supabase vs Pinecone: I Migrated My Production AI System and Here’s What Actually Matters | by Dee | Jul, 2025 | Medium, https://medium.com/@deeflect/supabase-vs-pinecone-i-migrated-my-production-ai-system-and-heres-what-actually-matters-7b2f2ebd59ee
  47. Pinecone vs. Postgres pgvector: For vector search, easy isn’t so easy, https://www.pinecone.io/blog/pinecone-vs-pgvector/
  48. Pricing - Pinecone, https://www.pinecone.io/pricing/
  49. Understanding cost - Pinecone Docs, https://docs.pinecone.io/guides/organizations/manage-cost/understanding-cost
  50. Compare Supabase vs. Weaviate - G2, https://www.g2.com/compare/supabase-supabase-vs-weaviate
  51. Vector database : pgvector vs milvus vs weaviate. : r/LocalLLaMA - Reddit, https://www.reddit.com/r/LocalLLaMA/comments/1e63m16/vector_database_pgvector_vs_milvus_vs_weaviate/
  52. Optimizing RAG: A Guide to Choosing the Right Vector Database | by Mutahar Ali - Medium, https://medium.com/@mutahar789/optimizing-rag-a-guide-to-choosing-the-right-vector-database-480f71a33139
  53. Compare PG Vector vs. Weaviate - G2, https://www.g2.com/compare/pg-vector-vs-weaviate
  54. Mastering RAG: How to Select an Embedding Model - Galileo AI, https://galileo.ai/blog/mastering-rag-how-to-select-an-embedding-model
  55. Choosing an Embedding Model - Pinecone, https://www.pinecone.io/learn/series/rag/embedding-models-rundown/
  56. Choosing the Right Embedding Model for Your Data - Zilliz blog, https://zilliz.com/blog/choosing-the-right-embedding-model-for-your-data
  57. Performance Tips for Developers Using Postgres and pgvector - DEV Community, https://dev.to/shiviyer/performance-tips-for-developers-using-postgres-and-pgvector-l7g
  58. Query pgvector — Vector Operations in PostgreSQL using pgvector - UnfoldAI, https://unfoldai.com/query-pgvector/