벡터 인덱스
요약 Apache Doris 4.0에는
ARRAY<FLOAT>컬럼을 위한 네이티브 ANN 인덱스가 추가되었습니다. 인덱스는CREATE TABLE안에서(또는CREATE INDEX ... USING ANN으로) 선언합니다. HNSW와 IVF 중 알고리즘을 선택하고, L2와 내적 중 거리 척도를 선택한 다음,l2_distance_approximate또는inner_product_approximate를ORDER BY ... LIMIT k에서 호출하면 됩니다. Faiss를 기반으로 하는 벡터 인덱스는 TopN 처리 전에 사전 필터링을 수행하므로WHERE조건이 정확하게 적용됩니다.

Apache Doris에서 벡터 인덱스를 사용하는 이유는 무엇인가요?
Apache Doris 벡터 인덱스를 사용하면 분석용 데이터 웨어하우스와 별도로 벡터 데이터베이스를 운영할 필요가 없습니다. 벡터 검색이 필요할 때 흔히 선택하는 방법은 두 번째 클러스터를 추가하는 것입니다. 이 방법도 가능하지만, 비용은 두 번 부담하게 됩니다. 금전적인 비용으로 한 번, 키워드 필터는 한쪽에 있고 임베딩은 다른 쪽에 있는 두 시스템의 운영 부담으로 또 한 번입니다.
- 단지 "가장 가까운 벡터 10개 찾기"를 수행하려고 별도 클러스터의 규모를 산정하고, 모니터링하며, 비용을 지불해야 합니다.
- 한쪽에서만 행을 갱신하면 분석 테이블과 벡터 저장소의 데이터가 서로 달라집니다.
- SQL 엔진이 벡터에 접근할 수 없어 애플리케이션에서 쿼리를 여러 시스템으로 나누어 보내고 결과를 병합하는 연계 코드를 작성해야 합니다.
Apache Doris는 벡터 인덱스를 다른 데이터와 같은 테이블에 통합합니다. 하나의 파이프라인으로 데이터를 적재하고, 하나의 SQL 쿼리로 조회할 수 있습니다.
Apache Doris 벡터 인덱스란 무엇인가요?
Apache Doris 벡터 인덱스는 벡터 타입 컬럼에 적용하는 ANN(Approximate Nearest Neighbor) 보조 인덱스입니다. 새로운 컬럼 타입을 도입하지 않고 벡터를 고정 차원의 ARRAY<FLOAT>로 저장합니다. 인덱스는 데이터와 함께 저장되고 세그먼트 단위로 구축되며, 플래너가 ORDER BY에서 근사 거리 함수를 발견하면 사용됩니다.
주요 용어
ARRAY<FLOAT>: Apache Doris에서 벡터를 저장하는 방식입니다. 컬럼은NOT NULL이어야 하며, 모든 행의 길이는 인덱스의dim과 같아야 합니다.USING ANN: 인덱스를 정의하는 절입니다. 속성으로 알고리즘(hnsw,ivf,ivf_on_disk), 거리 척도(l2_distance또는inner_product), 차원을 선택합니다.- HNSW: 기본 그래프 기반 알고리즘입니다. 속도가 빠르고 재현율이 높으며, 메모리에 상주해야 합니다.
- IVF / IVF on-disk: 메모리가 제한된 환경에서 더 큰 데이터 집합을 처리하기 위한 역파일 알고리즘입니다.
l2_distance_approximate/inner_product_approximate: 인덱스 사용을 유도하는 SQL 함수입니다. 이름에_approximate가 없는 버전도 있지만, 이 경우 완전 탐색으로 처리됩니다.
Apache Doris 벡터 인덱스는 어떻게 작동하나요?
Apache Doris 벡터 인덱스의 수명 주기는 데이터 적재 시점의 구축, 쿼리 패턴 인식, 사전 필터링, 세그먼트별 TopN 병합, 세션 설정을 통한 재현율 조정이라는 다섯 단계로 이루어집니다.
- 데이터 적재 시점에 구축합니다. 세그먼트를 기록할 때 Apache Doris는 컬럼을 Faiss에 전달하고 데이터와 함께 인덱스 파일을 구축합니다. 세그먼트마다 인덱스가 하나씩 생성되며, 별도의 구축 작업은 필요하지 않습니다.
- 플랜에서 패턴을 인식합니다.
ORDER BY l2_distance_approximate(col, [...]) LIMIT k형태의 쿼리는 스토리지 측의AnnTopN연산자를 사용하도록 재작성됩니다. 벡터 리터럴은 LIMIT과 함께 푸시다운됩니다. - 사전 필터링 후 TopN을 수행합니다.
WHERE절이 있으면 Apache Doris는 먼저 조건을 평가한 뒤, 조건을 통과한 데이터에 ANN TopN을 실행합니다. 따라서 필터로 대상이 크게 줄어드는 경우에도 재현율을 유지할 수 있습니다. 조건에 사용된 컬럼에는 자체 보조 인덱스(예: 역색인)가 있어야 합니다. 그렇지 않으면 엔진은 결과의 정확성을 유지하기 위해 해당 행에 완전 탐색을 적용합니다. - 세그먼트별 로컬 TopN을 구한 뒤 병합합니다. 각 세그먼트는 가장 가까운 k개를 반환합니다. TopN 연산자는 세그먼트와 태블릿 전체의 결과를 병합하여 전역 k개를 구합니다.
- 쿼리 실행 시 조정할 수 있습니다.
hnsw_ef_search같은 세션 변수로 후보 큐를 확장하면 지연 시간이 늘어나는 대신 재현율을 높일 수 있습니다. 기본값은 보수적으로 설정되어 있으므로, 목표 재현율이 있다면 값을 조정하세요.
빠른 시작
CREATE TABLE docs (
id INT NOT NULL,
embedding ARRAY<FLOAT> NOT NULL,
INDEX idx_emb (embedding) USING ANN PROPERTIES(
"index_type" = "hnsw",
"metric_type" = "l2_distance",
"dim" = "3"
)
) DUPLICATE KEY(id) DISTRIBUTED BY HASH(id) BUCKETS 1;
INSERT INTO docs VALUES
(1, [1.0, 2.0, 3.0]),
(2, [0.5, 2.1, 2.9]),
(3, [10.0, 10.0, 10.0]);
SELECT id, l2_distance_approximate(embedding, [1.0, 2.0, 3.0]) AS dist
FROM docs ORDER BY dist LIMIT 3;
예상 결과
+------+------------+
| id | dist |
+------+------------+
| 1 | 0 |
| 2 | 0.51961523 |
| 3 | 13.928389 |
+------+------------+
쿼리 벡터는 id=1의 벡터와 정확히 일치합니다(거리 0). ANN 인덱스는 가까운 두 이웃을 먼저 배치하고 멀리 떨어진 벡터를 마지막에 배치합니다. 같은 형태의 쿼리를 SIFT-1M 데이터 세트(1백만 개의 128차원 벡터)에 실행하면 인덱스를 사용할 때는 약 20 ms, 사용하지 않을 때는 약 290 ms가 걸립니다. 두 수치 모두 벡터 검색 개요에 나온 값입니다.
Apache Doris 벡터 인덱스는 언제 사용해야 하나요?
Apache Doris 벡터 인덱스는 기존에 필터링과 집계에 사용하는 구조화된 컬럼과 임베딩을 같은 테이블에 저장하는 모든 워크로드에 적합합니다.
적합한 경우
- 테넌트 ID, 문서 유형, 시간 등 필터 컬럼을 같은 테이블에 저장하는 RAG 검색. 필터링과 벡터 조회를 하나의 쿼리로 수행하려는 경우입니다.
- 다른 대시보드에서도 이미 활용하는 상품 또는 콘텐츠 메타데이터와 임베딩을 함께 저장하는 추천 후보 검색 및 "유사 항목 찾기" 기능.
- 이상 탐지 또는 "거리 X 이내의 모든 항목 찾기" 워크로드. 근사 범위 검색(
WHERE l2_distance_approximate(...) > 300)으로 처리할 수 있습니다. MATCH_*텍스트 조건과 벡터 순위를 결합하는 하이브리드 검색. 역색인은 사전 필터링을 수행하고 ANN 인덱스는 순위를 매깁니다. 하이브리드 검색을 참고하세요.
적합하지 않은 경우
- 십억 개 규모의 벡터에서 필터나 SQL 분석 없이 ANN 검색만 수행하는 경우. 전용 벡터 데이터베이스가 운영 비용이 더 낮고 QPS당 메모리 사용량도 더 적을 수 있습니다.
AGGREGATE KEY테이블 또는 merge-on-write를 사용하지 않는UNIQUE KEY테이블. 현재 ANN 인덱스는DUPLICATE KEY또는 MoW 방식의UNIQUE KEY가 필요합니다.- NULL을 허용하는 벡터 컬럼이나 길이가 맞지 않는 행. 컬럼은
NOT NULL ARRAY<FLOAT>이어야 하며, 모든 행의 길이가 선언된dim과 정확히 일치해야 합니다. 형태가 맞지 않으면 데이터 적재에 실패합니다. score()와 거리 함수를 같은ORDER BY에서 사용하는 경우. TopN 푸시다운은 정렬 표현식을 하나만 허용합니다. BM25와 ANN 점수를 모두 결합해야 한다면 SQL 상위 계층에서 결합하세요.- 코사인 유사도를
cosine_distance로 호출하는 경우. Apache Doris는 코사인 척도를 지원하지 않습니다. 벡터를 삽입하기 전에 정규화하고inner_product를 사용하세요. 단위 벡터에서는 코사인 유사도와 내적이 같습니다.
성능 / 수치
아래 수치는 프로젝트에서 공개한 Cohere-MEDIUM-1M 벤치마크 결과입니다(768차원, 벡터 1M개, FE 32C 64GB + BE 32C 64GB).
| 동시 실행 수 | 방식 | QPS | 평균 지연 시간 | P99 지연 시간 | 재현율 |
|---|---|---|---|---|---|
| 240 | HNSW (FLAT) | 3,340 | 71 ms | 163 ms | 91.0% |
| 240 | HNSW + SQ INT8 | 3,189 | 75 ms | 160 ms | 88.3% |
| 240 | 완전 탐색(인덱스 없음) | 3.7 | 25.6 s | 29.4 s | 100% |
출처: 벡터 인덱스 성능. 이 수치는 워크로드별 성능을 보장하지는 않으므로 참고 기준으로 활용하세요. 같은 페이지에서는 SQ8 양자화를 적용하면 인덱스 크기가 FLAT의 약 삼분의 일로 줄어들며, 위에서 확인할 수 있듯 재현율은 소폭 낮아진다고 설명합니다.
더 읽어보기
- 하이브리드 검색: ANN 인덱스와 역색인을 하나의 SQL 문에서 결합하는 방법.
- 벡터 검색 개요: 인덱스 속성, 쿼리 패턴, 제한 사항에 대한 전체 참조 문서.
- HNSW 심층 분석:
max_degree,ef_construction,ef_search가 재현율과 지연 시간 사이의 균형을 조정하는 방식. - IVF on-disk: 벡터 데이터 집합을 BE 메모리에 더 이상 담을 수 없을 때 사용하는 옵션.
- 실무 가이드: 데이터 준비, 데이터 적재, 튜닝을 포함한 전체 과정 안내.
- 임베딩:
EMBED()SQL 함수는 텍스트와 미디어를 이 인덱스가 읽는ARRAY<FLOAT>벡터로 변환합니다. - AI 개요: 벡터 검색과 Doris의 다른 AI 기능이 어떻게 연계되는지 설명합니다.