벡터 쿼리 실행 의미론
벡터 쿼리 실행 의미론 (Vector Query Execution Semantics)
Apache Pinot는 필터링된 근사 최근접 이웃(ANN) 검색, 거리-기반 임계값 필터링, 복합 검색 전략(compound retrieval) 같은 고급 벡터 쿼리 기능을 지원해요. 이 문서는 벡터 쿼리에 사용할 수 있는 실행 모드, 쿼리 옵션, 필터링 패턴을 설명해요.
출처: 문서
본문
개요
Pinot의 벡터 쿼리는 다음을 지원해요.
vectorDistanceThreshold쿼리 옵션을 통한 거리 임계값 필터링VECTOR_SIMILARITY와 메타데이터 필터를 결합한 필터링된 ANN- EXPLAIN 출력에서 볼 수 있는 8가지 명시적 실행 모드
- 다양한 벡터 인덱스 타입(HNSW, IVF_FLAT, IVF_PQ, IVF_ON_DISK)의 백엔드별 기능
upsert 및 삭제된 행의 queryable-document 범위
Pinot는 벡터 후보 생성 전에 세그먼트의 queryable-document 스냅샷을 적용해요. 이는 full-upsert 테이블, delete tombstone, skipUpsertDelete를 사용하는 쿼리에 중요해요. 오래된 물리적 행 버전과 삭제된 행이 세그먼트별 top-K 후보 슬롯을 소비한 후 나중에 필터 단계에서 사라질 수 없도록 하기 위함이에요. 따라서 VECTOR_SIMILARITY는 쿼리 계획의 나머지 부분과 동일한 current-row 뷰에서 후보를 반환해요.
실행 경로는 세그먼트의 벡터 리더에 따라 달라져요.
- filter-aware 리더는 queryable-document 범위를 받고 필터링된 ANN 검색을 수행해요.
- 후보 생성을 제한할 수 없는 리더는 queryable documents에 대한 정확한 스캔(exact scan)을 위해 우회돼요.
- 빈 queryable-document 범위는 벡터 검색을 실행하지 않고 후보를 반환하지 않아요.
- 필터링된 검색도 forward index에서의 정확한 스캔도 사용할 수 없으면 쿼리는 queryable-document 범위 밖의 후보를 반환하는 대신 실패해요.
정확한 스캔 대체 경로는 지연 시간보다 정확도를 우선해요. 그 비용은 queryable documents 수 곱하기 벡터 차원에 비례해요. upsert 테이블의 소비 세그먼트는 변경 가능한 벡터 리더가 filter-aware가 아닐 때 이 경로를 사용할 수 있으며, filter-aware 인덱스가 있는 불변 세그먼트는 계속 필터링된 ANN을 사용해요.
서버 계획이 활성화되면 queryable-document 범위가 벡터 검색을 제약할 때 EXPLAIN은 requiredDocIdFilterApplied: true와 requiredDocIdFilterCardinality를 보고해요. 정확한 스캔 대체 경로는 fallbackReason으로도 그 이유를 보고해요.
벡터 거리 임계값 쿼리 옵션
vectorDistanceThreshold 쿼리 옵션은 벡터 유사도 쿼리에서 거리-기반 필터링을 활성화해요. 이렇게 하면 고정된 top-K 결과 집합 대신 지정된 거리 임계값 내의 모든 벡터를 검색할 수 있어요.
구문
SET vectorDistanceThreshold = <threshold_value>;
SELECT <columns>
FROM <table>
WHERE VECTOR_SIMILARITY(column, ARRAY[...], topK)
ORDER BY <distance_function> ASC
LIMIT <limit>;
사용법
vectorDistanceThreshold가 설정되면 Pinot는 top-K로 제한되지 않고 지정된 거리 내의 모든 결과를 반환해요. 이는 의미론적 검색, 유사도 탐지, 특정 신뢰 수준을 넘는 모든 관련 일치 항목이 필요한 작업에 유용해요.
예시: 임계값 기반 검색
코사인 거리 0.3 이내의 쿼리 임베딩과 유사한 모든 제품을 찾기:
SET vectorDistanceThreshold = 0.3;
SELECT ProductId,
Summary,
cosineDistance(embedding, ARRAY[0.12, 0.34, 0.56, ...]) AS dist
FROM products
WHERE VECTOR_SIMILARITY(embedding, ARRAY[0.12, 0.34, 0.56, ...], 100)
ORDER BY dist ASC
LIMIT 1000;
이 예시에서:
VECTOR_SIMILARITY조건은 최대 100개의 ANN 후보를 검색해요.- 거리 함수 결과에 적용된
vectorDistanceThreshold = 0.3필터는 코사인 거리 <= 0.3인 제품만 반환되도록 해요. - 결과는 거리 오름차순으로 정렬돼요.
실행 모드
Pinot는 벡터 쿼리에 8가지 구별되는 실행 모드를 사용하며, 각각은 쿼리 구조와 사용 가능한 인덱스에 따라 선택돼요. 실행 모드는 EXPLAIN 출력의 executionMode 필드에서 볼 수 있어요.
1. ANN_TOP_K (기본값)
선택 조건: 메타데이터 필터나 거리 임계값이 없는 단순 VECTOR_SIMILARITY
동작:
- 순수 근사 최근접 이웃 검색을 실행해요.
- 벡터 유사도별로 정확히 top-K 결과를 반환해요.
- ANN 조회 후 필터링을 적용하지 않아요.
- 가장 빠른 실행 경로예요.
예시 쿼리:
SELECT ProductId,
cosineDistance(embedding, ARRAY[0.12, 0.34, 0.56, ...]) AS dist
FROM products
WHERE VECTOR_SIMILARITY(embedding, ARRAY[0.12, 0.34, 0.56, ...], 10)
ORDER BY dist ASC
LIMIT 10;
EXPLAIN 출력:
executionMode: ANN_TOP_K
2. ANN_TOP_K_WITH_RERANK
선택 조건: vectorExactRerank=true가 있는 VECTOR_SIMILARITY
동작:
- 벡터 인덱스를 사용해 ANN 후보를 검색해요.
- forward index에서 정확한 거리 계산으로 후보를 재순위화(리랭크)해요.
- 추가 정확한 거리 계산 비용으로 정확도를 향상시켜요.
- 인덱스 거리가 근사치인 IVF_PQ(기본적으로 활성화)에 권장돼요.
예시 쿼리:
SET vectorExactRerank = true;
SELECT ProductId,
cosineDistance(embedding, ARRAY[0.12, 0.34, 0.56, ...]) AS dist
FROM products
WHERE VECTOR_SIMILARITY(embedding, ARRAY[0.12, 0.34, 0.56, ...], 20)
ORDER BY dist ASC
LIMIT 10;
EXPLAIN 출력:
executionMode: ANN_TOP_K_WITH_RERANK
3. ANN_THEN_FILTER
선택 조건: 벡터가 아닌 메타데이터 필터(거리 임계값 없음)와 결합된 VECTOR_SIMILARITY
동작:
- 벡터 유사도에 대해 ANN을 실행해 top-K 후보를 얻어요.
- 결과에 메타데이터 필터(예:
AND category = 'electronics')를 적용해요. - 거리로 재순위화하지 않아요. 필터링은 ANN 후에 발생해요.
- 의미론적 검색과 속성-기반 필터링을 결합하는 데 유용해요.
예시 쿼리:
SELECT ProductId,
Summary,
cosineDistance(embedding, ARRAY[0.12, 0.34, 0.56, ...]) AS dist
FROM products
WHERE VECTOR_SIMILARITY(embedding, ARRAY[0.12, 0.34, 0.56, ...], 50)
AND category = 'electronics'
ORDER BY dist ASC
LIMIT 10;
EXPLAIN 출력:
executionMode: ANN_THEN_FILTER
4. ANN_THEN_FILTER_THEN_RERANK
선택 조건: 메타데이터 필터 AND vectorExactRerank=true가 있는 VECTOR_SIMILARITY
동작:
- ANN을 실행해 후보를 얻어요.
- 메타데이터 필터를 적용해요.
- 정확한 거리로 필터링된 결과를 재순위화해요.
- 근사 인덱스가 있는 필터링된 쿼리에 최고의 정확도를 제공해요.
예시 쿼리:
SET vectorExactRerank = true;
SELECT ProductId,
Summary,
cosineDistance(embedding, ARRAY[0.12, 0.34, 0.56, ...]) AS dist
FROM products
WHERE VECTOR_SIMILARITY(embedding, ARRAY[0.12, 0.34, 0.56, ...], 50)
AND category = 'electronics'
ORDER BY dist ASC
LIMIT 10;
EXPLAIN 출력:
executionMode: ANN_THEN_FILTER_THEN_RERANK
5. FILTER_THEN_ANN
선택 조건: filter-aware 검색을 지원하는 백엔드(HNSW, IVF_FLAT, IVF_ON_DISK)에서 고도로 선택적인(selective) 메타데이터 필터와 결합된 VECTOR_SIMILARITY. 적응형 플래너는 필터 선택도가 낮을 때(행의 30% 미만이 필터를 통과) 이 모드를 선택해요.
동작:
- 메타데이터 필터를 먼저 평가해 일치하는 행 ID의 비트맵을 만들어요.
FilterAwareVectorIndexReader를 통해 비트맵을 벡터 인덱스에 전달해요.- ANN 탐색은 비트맵의 벡터만 고려해, 선택적 필터에서 재현율(recall)을 향상시켜요.
- 필터링된 벡터 공간에서 최대 top-K 결과를 반환해요.
예시 쿼리:
SELECT ProductId,
Brand,
cosineDistance(embedding, ARRAY[0.12, 0.34, 0.56, ...]) AS dist
FROM products
WHERE VECTOR_SIMILARITY(embedding, ARRAY[0.12, 0.34, 0.56, ...], 10)
AND category = 'rare_collectibles'
ORDER BY dist ASC
LIMIT 10;
EXPLAIN 출력:
executionMode: FILTER_THEN_ANN
참고:
FilterPlanNode의 적응형 플래너는 필터 선택도에 따라FILTER_THEN_ANN과ANN_THEN_FILTER를 자동으로 선택해요. 쿼리 옵션을 설정할 필요 없이 Pinot가 세그먼트별로 더 빠른 전략을 골라요.
6. ANN_THRESHOLD_SCAN
선택 조건: vectorDistanceThreshold가 있는 VECTOR_SIMILARITY(메타데이터 필터 없음)
동작:
- ANN 검색을 실행해요.
- 반환된 후보에 거리 임계값 필터를 적용해요.
- 거리 임계값 내의 모든 결과를 반환해요.
- 신뢰-기반 검색에 유용해요.
예시 쿼리:
SET vectorDistanceThreshold = 0.3;
SELECT ProductId,
cosineDistance(embedding, ARRAY[0.12, 0.34, 0.56, ...]) AS dist
FROM products
WHERE VECTOR_SIMILARITY(embedding, ARRAY[0.12, 0.34, 0.56, ...], 100)
ORDER BY dist ASC
LIMIT 1000;
EXPLAIN 출력:
executionMode: ANN_THRESHOLD_SCAN
7. ANN_THRESHOLD_THEN_FILTER
선택 조건: vectorDistanceThreshold AND 메타데이터 필터가 모두 있는 VECTOR_SIMILARITY
동작:
- ANN 검색을 실행해요.
- 거리 임계값 필터를 적용해요.
- 임계값으로 필터링된 결과에 메타데이터 필터를 적용해요.
- 신뢰-기반과 속성-기반 필터링을 결합해요.
예시 쿼리:
SET vectorDistanceThreshold = 0.3;
SELECT ProductId,
Summary,
cosineDistance(embedding, ARRAY[0.12, 0.34, 0.56, ...]) AS dist
FROM products
WHERE VECTOR_SIMILARITY(embedding, ARRAY[0.12, 0.34, 0.56, ...], 100)
AND category = 'electronics'
ORDER BY dist ASC
LIMIT 1000;
EXPLAIN 출력:
executionMode: ANN_THRESHOLD_THEN_FILTER
8. EXACT_SCAN
선택 조건: 세그먼트에 벡터 인덱스가 없음(예: IVF_FLAT, IVF_PQ 또는 IVF_ON_DISK가 있는 실시간 세그먼트)
동작:
- 정확한 forward index 스캔으로 대체돼요.
- 모든 벡터를 스캔하고 전체 세그먼트에 대한 거리를 계산해요.
- ANN보다 느리지만 정확한 결과를 제공해요.
- 벡터 인덱스가 없는 세그먼트에 자동으로 적용돼요.
- IVF_FLAT, IVF_PQ, IVF_ON_DISK는 실시간/변경 가능한 세그먼트를 지원하지 않아요. HNSW는 둘 다 지원해요.
언제 발생하나요:
- 세그먼트 롤오버 전 실시간 세그먼트의 새로 수집된 데이터
- 벡터 인덱스가 구성되지 않은 테이블
- 인덱스 누락으로 인한 의도적인 대체
EXPLAIN 출력:
executionMode: EXACT_SCAN
fallbackReason: ivf_pq_index_unavailable
필터링된 ANN: 벡터와 메타데이터 필터 결합
Pinot는 AND 표현식에서 VECTOR_SIMILARITY가 메타데이터 필터와 결합된 패턴을 자동으로 감지하고 최적화해요. 이를 통해 효율적인 필터링된 최근접 이웃 검색이 가능해져요.
패턴: AND(VECTOR_SIMILARITY, 비-벡터 필터)
쿼리가 AND 절에 벡터 유사도 조건과 다른 비-벡터 필터를 모두 포함하면 Pinot의 FilterPlanNode는 다음과 같이 실행을 최적화해요.
- ANN 조회 단계: 벡터 인덱스를 사용해 후보를 검색해요.
- 필터 단계: 후보 집합에 메타데이터 필터를 적용해요.
- 리랭크 단계(선택): 활성화된 경우 정확한 리랭크를 수행해요.
예시: 카테고리에서 유사한 제품 찾기
SELECT ProductId,
Brand,
Price,
l2Distance(embedding, ARRAY[0.1, 0.2, 0.3, ...]) AS dist
FROM products
WHERE VECTOR_SIMILARITY(embedding, ARRAY[0.1, 0.2, 0.3, ...], 50)
AND category = 'electronics'
AND price < 200
ORDER BY dist ASC
LIMIT 10;
실행 흐름:
- ANN: 쿼리 임베딩에 가장 가까운 최대 50개 제품 검색해요.
- 메타데이터 필터:
category = 'electronics'ANDprice < 200인 것만 유지해요. - 순위: 정확한 L2 거리로 정렬해요.
- 제한: 상위 10개 반환해요.
EXPLAIN 출력:
executionMode: ANN_THEN_FILTER
예시: 정확한 리랭킹이 있는 필터링된 ANN
근사 인덱스(특히 IVF_PQ)에서 더 나은 정확도를 위해:
SET vectorExactRerank = true;
SELECT ProductId,
Brand,
l2Distance(embedding, ARRAY[0.1, 0.2, 0.3, ...]) AS dist
FROM products
WHERE VECTOR_SIMILARITY(embedding, ARRAY[0.1, 0.2, 0.3, ...], 100)
AND category = 'electronics'
ORDER BY dist ASC
LIMIT 10;
실행 흐름:
- ANN: 100개 후보 검색해요.
- 메타데이터 필터: 전자제품만 유지해요.
- 정확한 리랭크: 필터링된 후보의 정확한 거리를 계산해요.
- 순위 및 제한: 정확한 거리로 상위 10개 반환해요.
EXPLAIN 출력:
executionMode: ANN_THEN_FILTER_THEN_RERANK
EXPLAIN으로 실행 모드 보기
explainAskingServers=true와 함께 EXPLAIN 문을 사용해 실행 모드와 백엔드 세부 정보를 포함한 벡터 쿼리 실행 계획을 볼 수 있어요.
기본 EXPLAIN
EXPLAIN PLAN FOR
SELECT ProductId,
cosineDistance(embedding, ARRAY[0.12, 0.34, 0.56, ...]) AS dist
FROM products
WHERE VECTOR_SIMILARITY(embedding, ARRAY[0.12, 0.34, 0.56, ...], 10)
ORDER BY dist ASC
LIMIT 10;
서버 계획이 있는 상세 EXPLAIN
SET explainAskingServers = true;
EXPLAIN PLAN FOR
SELECT ProductId,
cosineDistance(embedding, ARRAY[0.12, 0.34, 0.56, ...]) AS dist
FROM products
WHERE VECTOR_SIMILARITY(embedding, ARRAY[0.12, 0.34, 0.56, ...], 50)
AND category = 'electronics'
ORDER BY dist ASC
LIMIT 10;
출력에는 다음이 포함돼요.
- executionMode: 8가지 모드 중 어떤 것이 사용되는지 (예:
ANN_THEN_FILTER) - backend: 벡터 인덱스 타입 (HNSW, IVF_FLAT, IVF_PQ, IVF_ON_DISK, 또는 EXACT)
- distanceFunction: 구성된 거리 메트릭 (COSINE, EUCLIDEAN 등)
- nprobe: 프로브된 클러스터 수 (IVF_FLAT/IVF_PQ만)
- exactRerank: 정확한 리랭킹이 활성화되었는지 (각인)
- candidateCount: 검사된 후보 수
- fallbackReason: 해당하는 경우 (예:
ivf_pq_index_unavailable) - requiredDocIdFilterApplied: queryable-document 범위가 후보 생성을 제약했는지
- requiredDocIdFilterCardinality: 해당 필수 범위의 문서 ID 수
벡터 쿼리 쿼리 옵션 참조
벡터 쿼리에서 다음 쿼리 옵션은 실행 동작을 제어해요.
| 옵션 | 효과 | 기본값 |
|---|---|---|
vectorDistanceThreshold |
이 거리 임계값 내의 모든 결과를 반환해요. | 설정 안 됨 (top-K 사용) |
vectorExactRerank |
ANN 후보를 정확한 거리로 재순위화해요. | IVF_PQ는 true; HNSW/IVF_FLAT는 false |
vectorNprobe |
프로브할 클러스터 수 (IVF_FLAT, IVF_PQ, IVF_ON_DISK) | 4 |
vectorMaxCandidates |
정확한 리랭킹 전에 검사할 최대 ANN 후보 | topK * 10 |
vectorEfSearch |
HNSW 검색 빔 폭 — 그래프 탐색이 방문하는 노드 수 제어 | 인덱스 구성에서 유래 |
vectorUseRelativeDistance |
HNSW 경쟁적 가지치기 토글 — 일부 데이터 분포에서 비활성화하면 재현율이 향상될 수 있음 | true |
vectorUseBoundedQueue |
HNSW 경계 top-K 수집기 토글 | true |
explainAskingServers |
EXPLAIN에 세그먼트 수준 실행 계획 포함 | false |
쿼리 옵션 설정
SET vectorDistanceThreshold = 0.3;
SET vectorExactRerank = true;
SET vectorNprobe = 8;
SET explainAskingServers = true;
SELECT ProductId, cosineDistance(embedding, ARRAY[...]) AS dist
FROM products
WHERE VECTOR_SIMILARITY(embedding, ARRAY[...], 50)
ORDER BY dist ASC
LIMIT 10;
복합 검색 전략 (Compound Retrieval)
복합 검색은 여러 필터링과 순위화 기법을 결합해 정확도와 성능의 균형을 맞춰요.
전략 1: 리랭킹이 있는 고재현율 ANN
더 많은 후보를 검색하고 리랭크해 정확도를 높여요:
SET vectorExactRerank = true;
SELECT ProductId,
cosineDistance(embedding, ARRAY[0.12, 0.34, 0.56, ...]) AS dist
FROM products
WHERE VECTOR_SIMILARITY(embedding, ARRAY[0.12, 0.34, 0.56, ...], 100)
ORDER BY dist ASC
LIMIT 10;
트레이드오프: 특히 근사 인덱스에서 지연 시간은 높아지지만 정확도가 더 좋아져요.
전략 2: 메타데이터가 있는 필터링된 ANN
도메인-특정 검색을 위해 벡터와 속성 필터링을 결합해요:
SELECT ProductId,
Brand,
l2Distance(embedding, ARRAY[0.1, 0.2, 0.3, ...]) AS dist
FROM products
WHERE VECTOR_SIMILARITY(embedding, ARRAY[0.1, 0.2, 0.3, ...], 50)
AND inStock = true
AND rating >= 4.0
ORDER BY dist ASC
LIMIT 10;
이점: 후보 집합을 일찍 좁혀 리랭킹 비용을 줄여요.
전략 3: 임계값 기반 검색
신뢰 임계값을 충족하는 모든 결과를 반환해요:
SET vectorDistanceThreshold = 0.2;
SELECT ProductId,
Summary,
cosineDistance(embedding, ARRAY[0.12, 0.34, 0.56, ...]) AS dist
FROM products
WHERE VECTOR_SIMILARITY(embedding, ARRAY[0.12, 0.34, 0.56, ...], 200)
ORDER BY dist ASC;
사용 사례: 고정된 top-K가 아니라 "충분히 관련 있는" 모든 결과를 반환해요.
전략 4: 필터링된 임계값 검색
임계값 필터링과 메타데이터 필터를 결합해요:
SET vectorDistanceThreshold = 0.25;
SELECT ProductId,
Summary,
cosineDistance(embedding, ARRAY[0.12, 0.34, 0.56, ...]) AS dist
FROM products
WHERE VECTOR_SIMILARITY(embedding, ARRAY[0.12, 0.34, 0.56, ...], 200)
AND category = 'Books'
ORDER BY dist ASC;
사용 사례: 특정 카테고리의 모든 관련 결과를 반환해요.
성능 고려사항
각 실행 모드를 언제 사용할까
| 모드 | 가장 적합한 경우 | 지연 시간 | 정확도 |
|---|---|---|---|
| ANN_TOP_K | 단순 유사도 검색 | 빠름 | 좋음 (인덱스에 따라) |
| ANN_TOP_K_WITH_RERANK | 근사 인덱스 (IVF_PQ) | 더 느림 | 우수 |
| ANN_THEN_FILTER | 카테고리/속성 필터링 (비선택적 필터) | 중간 | 좋음 |
| ANN_THEN_FILTER_THEN_RERANK | 정확한 필터링 검색 | 더 느림 | 우수 |
| FILTER_THEN_ANN | 고도로 선택적인 필터 (행의 70% 이상 제거) | 중간 | 우수 |
| ANN_THRESHOLD_SCAN | 신뢰-기반 필터링 | 다양함 | 좋음 |
| ANN_THRESHOLD_THEN_FILTER | 신뢰 + 카테고리 필터 | 더 느림 | 좋음 |
| EXACT_SCAN | 사용 가능한 인덱스가 없음 | 매우 느림 | 완벽함 |
튜닝 팁
- IVF_PQ의 경우: 양자화 손실을 보완하기 위해
vectorExactRerank = true(기본값)를 활성화해요. - 필터링된 쿼리의 경우: 더 많은 후보(더 큰 topK)를 검색하고 Pinot가 필터링하도록 해요. 이는 더 작은 topK보다 빠를 수 있어요.
- 임계값 쿼리의 경우: 모든 임계값 일치를 얻기 위해 충분한 후보를 검색해요. 넉넉한 topK를 사용해요.
- 고차원 벡터의 경우: 메모리 효율을 위해 IVF_PQ, 2 GB 힙 제한 없이 무제한 확장을 위해 IVF_ON_DISK, 최고 정확도를 위해 HNSW를 고려해요.
참고 자료 (See Also)
- 벡터 인덱스 문서 — 벡터 인덱스 구성 및 튜닝
- 벡터/유사도 함수 — 거리 함수 및 VECTOR_SIMILARITY 구문
- 쿼리 옵션 — 쿼리 시점 설정 전체 참조
- 쿼리 실행 — 일반 쿼리 실행 개념