Querying¶
AkasicDB vector 검색은 PostgreSQL의 ORDER BY ... LIMIT 패턴을 사용합니다. 인덱스가 없으면 exact search로 동작하고, AkasicDB vector 인덱스가 있으면 같은 쿼리가 ANN search로 실행될 수 있습니다.
Exact 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 |
Indexed ANN Search¶
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;
Filtered Search¶
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 비용에 모두 영향을 줍니다.