콘텐츠로 이동

Querying

AkasicDB vector 검색은 PostgreSQL의 ORDER BY ... LIMIT 패턴을 사용합니다. 인덱스가 없으면 exact search로 동작하고, AkasicDB vector 인덱스가 있으면 같은 쿼리가 ANN search로 실행될 수 있습니다.

인덱스가 없거나 planner가 인덱스를 선택하지 않으면 PostgreSQL은 조건에 맞는 row를 평가한 뒤 ORDER BY의 distance operator로 ordering을 계산합니다. 작은 데이터셋이나 ANN validation에서는 이 결과가 ground truth가 됩니다.

SELECT id, embedding <-> '[0.1,0.2,0.3]'::vector AS distance
  FROM items
 ORDER BY embedding <-> '[0.1,0.2,0.3]'::vector
 LIMIT 5;
Operator 의미
<-> Squared L2 distance
<#> Negative dot product
<=> Cosine distance

AkasicDB vector 인덱스가 있으면 ORDER BY embedding <operator> query_vector LIMIT k 형태의 쿼리가 ANN search로 실행될 수 있습니다. 인덱스를 만들 때 선택한 opclass와 ORDER BY operator는 같은 distance family에 속해야 합니다.

CREATE INDEX items_embedding_hnsw_idx
  ON items
  USING vectoron (embedding vector_l2_ops);

SELECT id
  FROM items
 ORDER BY embedding <-> '[0.1,0.2,0.3]'::vector
 LIMIT 10;

Search-time GUC는 index build option과 별개입니다. 예를 들어 HNSW의 ef_construction은 인덱스 생성 시점에 정하고, vectoron.hnsw_ef_search는 검색 시점의 탐색 폭을 정합니다.

Index Search-time GUC Default 설명
HNSW vectoron.hnsw_ef_search 100 HNSW 검색 후보 폭입니다. 값이 클수록 더 많은 후보를 평가하므로 CPU 작업량과 latency가 증가할 수 있습니다.
Vamana vectoron.vamana_l_search 100 Vamana 검색 후보 폭입니다. 값이 클수록 더 많은 후보를 평가하므로 CPU 작업량과 latency가 증가할 수 있습니다.
IVF vectoron.ivf_nprobe 10 검색할 IVF cluster 수입니다. 값이 클수록 더 많은 cluster를 스캔하므로 I/O 작업량과 latency가 증가할 수 있습니다.

위의 파라미터를 변경할 때에는 recall과 latency 변화를 확인하며 적절한 값을 찾으시기 바랍니다.

세션 전체에 적용하려면 일반 SET을 사용합니다.

SET vectoron.hnsw_ef_search = 100;
SET vectoron.ivf_nprobe = 10;
SET vectoron.vamana_l_search = 100;

Vector 검색은 PostgreSQL predicate와 함께 실행됩니다. Plan과 latency는 WHERE 조건의 selectivity, scalar index, vector index, search mode에 따라 달라집니다. 대상 workload의 filter 조건으로 측정합니다.

CREATE INDEX items_category_idx ON items (category_id);

SELECT id, category_id
  FROM items
 WHERE category_id = 3
 ORDER BY embedding <-> '[0.1,0.2,0.3]'::vector
 LIMIT 10;

AkasicDB의 planner는 ANN search와 관계형 필터링을 함께 고려합니다.

Search Mode

vectoron.search_mode는 vector search와 PostgreSQL query plan의 결합 방식을 선택합니다.

Mode 용도
vbase 기본 모드입니다. 필터가 포함된 일반 SQL 검색은 이 모드에서 시작합니다.
basic 필터 없는 vector search를 비교하거나 디버깅할 때 사용합니다. 사용 전에 VACUUM이 필요하며 filter 조건과 함께 쓰지 않습니다.

basic을 사용할 때는 세션 범위를 명확히 합니다.

SET vectoron.search_mode = 'basic';

SELECT id
  FROM items
 ORDER BY embedding <-> '[0.1,0.2,0.3]'::vector
 LIMIT 10;

비교가 끝나면 새 세션을 쓰거나 원하는 mode로 다시 설정합니다.

Query-Local Tuning

한 쿼리에만 탐색 폭을 바꾸려면 SET LOCAL을 사용합니다. SET LOCAL은 transaction 안에서만 유효하므로 항상 BEGIN/COMMIT 블록 안에 둡니다.

BEGIN;
SET LOCAL vectoron.hnsw_ef_search = 200;

SELECT id
  FROM items
 ORDER BY embedding <-> '[0.1,0.2,0.3]'::vector
 LIMIT 10;
COMMIT;

한 transaction 안에서 여러 search GUC를 함께 바꿀 수 있습니다.

BEGIN;
SET LOCAL vectoron.vamana_l_search = 200;
SET LOCAL vectoron.ivf_nprobe = 20;

SELECT id
  FROM items
 WHERE category_id = 3
 ORDER BY embedding <-> '[0.1,0.2,0.3]'::vector
 LIMIT 10;
COMMIT;

탐색 폭은 recall, latency, CPU 비용에 모두 영향을 줍니다.