LanceDB 인덱스, 뭘 고르면 RAG 검색이 안정적일까?

정답은 하나로 정해지지 않는다. 메타데이터 필터가 많은 RAG라면 IVF_PQ·IVF_RQ 계열을 먼저 검토하고, recall이 중요한 RAG라면 IVF_HNSW_* 계열을 같은 질의 세트로 직접 비교해야 한다. 2026년 기준 LanceDB 공식 문서도 "데이터 분포에 따라 결과가 달라지므로 실제 문서셋으로 재측정하라"고 못박고 있다.

이 글의 핵심

  • 기본값은 IVF_PQ이지만, 필터가 많은 워크로드에는 IVF_RQ/IVF_PQ가, 고recall이 필요하면 IVF_HNSW_*가 별도 후보다.
  • IVF_HNSW_FLAT·IVF_HNSW_SQ는 필터링 환경에서 지연시간 변동이 더 클 수 있다고 공식 문서가 밝힌다.
  • nprobes(기본 20)와 HNSW 후보 수(기본 limit×1.5)는 recall-latency 트레이드오프를 직접 조절하는 변수다.
  • 100억 벡터 p99 21ms, 1,066 QPS 같은 수치는 제품사의 특정 실험 구성 결과이며 일반 단일 노드 성능으로 치환하면 안 된다.
  • GPU 인덱싱은 검색이 아니라 인덱스 구축 단계를 가속하는 Enterprise 기능이다.

실제로 많이 걸리는 함정은 둘이다. 하나는 metric 설정을 기본값 l2로 두고 넘어가는 것인데, 임베딩이 정규화되어 있다면 dot, 정규화되지 않았다면 cosine을 써야 recall이 정상적으로 나온다. 공식 문서는 이 셋을 모두 제공하지만 모델에 맞춰 고르는 책임은 사용자에게 있다. 다른 하나는 신규 문서 추가 직후의 검색 품질을 테스트 케이스에 넣지 않는 것이다. 인덱스가 비동기로 갱신되는 동안 brute-force로 커버되는 범위와 fast_search()로 제외되는 범위가 다르기 때문에, 운영 중 "방금 올린 문서가 안 나온다"는 보고를 받고 나서야 알게 되는 경우가 흔하다.

메타데이터 필터가 많은 RAG는 어떤 인덱스가 유리할까?

필터가 자주 걸리는 워크로드라면 IVF_PQ 또는 IVF_RQ를 1순위로 검토할 근거가 있다. LanceDB 공식 문서는 where(...) 필터가 빈번한 경우 이 두 인덱스를 권장하고, 반대로 IVF_HNSW_FLAT·IVF_HNSW_SQ는 필터링 환경에서 지연시간 변동이 더 클 수 있다고 설명한다. 필터 없음, 단일 필터, 복합 필터 세 조건으로 나눠 p50/p95를 따로 재면 어느 인덱스가 자신의 데이터에 맞는지 드러난다.

실험에서 자주 생기는 착각은 "필터가 하나만 있으니 영향이 적을 것"이라는 가정이다. 복합 필터(예: 날짜 범위 + 카테고리 + 상태값)로 갈수록 파티션 스킵 효율이 떨어지는 인덱스가 있고, 이는 문서 수가 아니라 필터 선택도(selectivity)에 더 좌우된다. 따라서 비교표를 만들 때는 "필터 개수"가 아니라 "필터 결과가 전체의 몇 %를 남기는가"를 함께 기록해야 재현 가능한 결론이 된다. PQ 기반 인덱스는 압축을 쓰기 때문에 인덱스 크기와 recall 사이 균형을 노리지만, 압축으로 인한 품질 저하 폭은 임베딩 모델·차원·문서 중복도에 따라 달라진다는 점도 공식 문서가 명시한다.

recall을 더 끌어올리고 싶다면 HNSW 계열로 바꿔야 할까?

무조건 전환이 정답은 아니고, 같은 질의 세트로 recall@5/10과 latency를 같이 비교한 뒤 판단할 문제다. LanceDB의 HNSW는 독립된 최상위 인덱스가 아니라 IVF 파티션 내부에 결합된 구조이며, 지원 조합은 IVF_HNSW_FLAT, IVF_HNSW_PQ, IVF_HNSW_SQ 세 가지다. IVF의 확장성과 HNSW의 검색 품질을 동시에 노리는 설계지만, 그만큼 튜닝해야 할 파라미터도 늘어난다.

실제로 신경 써야 할 변수는 두 개다. 첫째는 nprobes로, SDK 기본값은 20이며 값을 올리면 recall은 개선되지만 지연시간도 함께 늘어난다. 둘째는 HNSW 후보 수인데, 기본값이 limit의 1.5배로 설정돼 있고 이 역시 늘리면 recall이 오르는 대신 latency가 올라간다. RAG에서 reranker를 쓴다면 limit, 후보 수, reranker 입력 개수 세 값을 고정한 채 하나씩만 바꿔가며 비교해야 어떤 변수가 품질에 기여했는지 구분할 수 있다. SDK 문서에 이 기본값들이 명시돼 있으니 버전이 바뀔 때마다 재확인하는 편이 안전하다.

LanceDB가 공개한 벤치마크 수치를 우리 서비스에 그대로 대입해도 될까?

그대로 대입하면 오해다. LanceDB Cloud가 1,500만 건 데이터에서 메타데이터 필터 포함 p50 30ms를 관측했다는 사례, 100억 벡터 실험에서 end-to-end p99 21ms를 보고한 블로그, 2025년 뉴스레터의 1,066 QPS 언급은 모두 특정 서비스 구성·하드웨어·실험 설계를 전제로 한 제품사 자체 수치다. 100억 벡터 p99 21ms 수치는 centroid routing, 분산 실행, RaBitQ 스캔, full-precision reranking을 포함한 구성의 결과라고 블로그 원문에 명시돼 있다.

이 수치들을 인용할 때는 반드시 "제품사 자체 실험"이라는 전제를 함께 적어야 하고, 로컬 LanceDB나 다른 클라우드 벡터DB와의 일반적인 우열 비교로 확대해서는 안 된다. 1,066 QPS 사례도 CPU/GPU 구성, 동시성, query limit, recall, 필터 조건이 공개된 독립 벤치마크인지 확인되지 않은 상태라 참고용 숫자 이상으로 쓰기 어렵다. 실사용 리뷰라면 이런 공개 수치는 "이 정도 규모에서 이런 설계가 가능하다"는 레퍼런스로만 두고, 실제 판단 근거는 자신의 문서셋·임베딩 모델·질의 세트로 직접 뽑은 recall@k와 p50/p95/p99 latency여야 한다.

인덱스 재구성·GPU 인덱싱·최신성 검증까지 비용으로 잡아야 할까?

그렇다. 검색 latency만 보고 비교 글을 마무리하면 운영 단계에서 비용이 터진다. LanceDB 문서는 IVF_FLAT의 대규모 학습이 느리고 메모리 집약적일 수 있다고 명시하므로, 인덱스 생성 시간, peak RAM/GPU 메모리, 인덱스 저장공간, 증분 데이터 재최적화(optimize()) 비용을 함께 기록해야 한다. GPU 인덱싱은 LanceDB Enterprise 기능으로 공개돼 있고, 자체 테스트에서는 1~8개 GPU 클러스터로 수십억 행 인덱스를 4시간 이내에 만들 수 있다고 설명하지만, 이는 Enterprise 조건에 한정된 수치이고 오픈소스 로컬 설치의 보장값이 아니다. GPU는 검색 실행이 아니라 인덱스 구축 단계를 가속하는 것이어서, 대량 일괄 적재형 RAG와 지속적 스트리밍 적재형 RAG는 운영 비용 구조 자체가 다르다.

최신성 비용도 따로 잡아야 한다. LanceDB Cloud는 인덱싱이 끝나기 전에도 신규 벡터를 brute-force로 검색해 노출하지만, 속도를 우선하는 fast_search()는 인덱스에 들어가지 않은 행을 검색 대상에서 제외한다. 문서가 자주 추가되는 RAG라면 "방금 추가된 문서가 검색되는가"를 테스트 케이스에 넣고, 인덱싱 전·후 latency를 분리해 기록해야 실사용 리뷰로서 의미가 있다. 공개되지 않은 가격은 추정하지 말고 "가격표 확인 필요"로 표시하는 편이 안전하다.

핵심 정리

  • 기본 선택지는 IVF_PQ, 필터 많은 워크로드는 IVF_RQ/IVF_PQ, 고recall이 필요하면 IVF_HNSW_* — 반드시 자신의 데이터로 재측정.
  • metric은 임베딩 정규화 여부에 맞춰 l2/cosine/dot 중 선택해야 recall이 왜곡되지 않는다.
  • nprobes(기본 20)와 HNSW 후보 수(기본 limit×1.5)는 recall-latency 트레이드오프의 핵심 노브다.
  • 30ms·21ms·1,066 QPS 같은 공개 수치는 제품사 자체 실험 조건의 결과이며 일반화하면 안 된다.
  • 인덱스 생성 시간·메모리·GPU 인덱싱 조건·신규 문서 최신성까지 포함해야 실사용 비용 비교가 완성된다.