벡터 쿼리 성능 조정

문서 버전을 선택하세요.

이 문서에서는 더 빠른 쿼리 성능과 더 나은 리콜을 위해 색인을 조정하는 방법을 보여줍니다.

ScaNN 색인 조정

ScaNN 색인은 트리 양자화 기반 색인을 사용합니다. 트리 양자화 기법에서 색인은 양자화 (또는 해싱) 함수와 함께 검색 트리를 학습합니다. 쿼리를 실행하면 검색 트리가 검색 공간을 가지치기하는 데 사용되고 양자화는 색인 크기를 압축하는 데 사용됩니다. 이 가지치기를 통해 쿼리 벡터와 데이터베이스 벡터 간의 유사성 (즉, 거리) 점수 매기기가 빨라집니다.

최근접 이웃 쿼리로 높은 초당 쿼리 수 (QPS)와 높은 재현율을 모두 달성하려면 데이터와 쿼리에 가장 적합한 방식으로 ScaNN 색인의 트리를 파티셔닝해야 합니다.

ScaNN 색인을 빌드하기 전에 다음을 완료하세요.

  • 데이터가 포함된 테이블이 이미 생성되어 있는지 확인합니다.
  • 색인을 생성하는 동안 문제가 발생하지 않도록 maintenance_work_memshared_buffers 플래그에 설정한 값이 총 머신 메모리보다 작은지 확인합니다.

조정 파라미터

다음 색인 매개변수와 데이터베이스 플래그는 재현율과 QPS의 적절한 균형을 찾기 위해 함께 사용됩니다. 모든 매개변수는 두 ScaNN 색인 유형에 적용됩니다.

조정 매개변수 설명 매개변수 유형
num_leaves 이 색인에 적용할 파티션 수입니다. 색인을 만들 때 적용하는 파티션 수는 색인 성능에 영향을 미칩니다. 정해진 수의 벡터에 대한 파티션을 늘리면 더 세분화된 색인이 생성되어 재현율과 쿼리 성능이 향상됩니다. 하지만 이렇게 하면 색인 생성 시간이 길어집니다.

3단계 트리는 2단계 트리보다 빠르게 빌드되므로 3단계 트리 색인을 생성할 때 num_leaves_value를 늘려 성능을 개선할 수 있습니다.
  • 2단계 색인: 이 값을 11048576 사이의 값으로 설정합니다.

    정확한 값을 선택하는 것이 확실하지 않다면 sqrt(ROWS)을 시작점으로 사용하세요. 여기서 ROWS은 벡터 행의 수입니다. 각 파티션이 보유하는 벡터 수는
    ROWS/sqrt(ROWS) = sqrt(ROWS)로 계산됩니다.

    2단계 트리 색인은 벡터 행이 1,000만 개 미만인 데이터 세트에서 만들 수 있으므로 각 파티션은 (sqrt(10M)) 벡터 미만인 3200 벡터를 보유합니다. 최적의 성능을 위해 각 파티션의 벡터 수를 최소화하는 것이 좋습니다.
  • 3단계 색인: 이 값을 11048576 사이의 값으로 설정합니다.

    정확한 값을 선택하는 것이 확실하지 않다면 power(ROWS, 2/3)를 시작점으로 사용하세요. 여기서 ROWS은 벡터 행의 수입니다. 각 파티션이 보유하는 벡터 수는
    ROWS/power(ROWS, 2/3) = power(ROWS, 1/3).

    에 의해 계산됩니다. 벡터 행이 1억 개 이상인 데이터 세트에서 3단계 트리 색인을 만들 수 있으므로 각 파티션은
    (power(100M, 1/3)) 벡터, 즉 465 벡터 이상을 보유합니다. 최적의 성능을 위해 각 파티션의 벡터 수를 최소화하는 것이 좋습니다.
색인 생성
quantizer K-means 트리에 사용할 양자화기의 유형입니다. 기본값은 SQ8로 설정되어 있어 쿼리 성능이 향상됩니다.

리콜을 개선하려면 FLAT로 설정하세요.
색인 생성
enable_pca 가능한 경우 임베딩 크기를 자동으로 줄이는 데 사용되는 차원 축소 기법인 주성분 분석 (PCA)을 사용 설정합니다. 이 옵션은 기본적으로 사용 설정되어 있습니다.

재현율이 저하되는 경우 false로 설정하세요.
색인 생성
scann.num_leaves_to_search 데이터베이스 플래그는 재현율과 QPS 간의 절충을 제어합니다. 기본값은 num_leaves에 설정된 값의 1% 입니다.

설정된 값이 높을수록 재현율이 높아지지만 QPS가 낮아지며, 그 반대의 경우도 마찬가지입니다.
쿼리 런타임
scann.max_top_neighbors_buffer_size 데이터베이스 플래그는 디스크 대신 메모리에서 스캔된 후보 이웃을 점수화하거나 순위를 매겨 필터링된 쿼리의 성능을 개선하는 데 사용되는 캐시의 크기를 지정합니다. 기본값은 20000입니다.

설정된 값이 높을수록 필터링된 쿼리의 QPS가 향상되지만 메모리 사용량이 증가합니다. 반대의 경우도 마찬가지입니다.
쿼리 런타임
scann.pre_reordering_num_neighbors 설정된 경우 데이터베이스 플래그는 초기 검색에서 후보 집합을 식별한 후 순서 변경 단계에서 고려할 후보 이웃 수를 지정합니다. 이 값을 쿼리에서 반환할 이웃 수보다 큰 값으로 설정합니다.

값이 높을수록 재현율이 높아지지만 이 접근 방식은 QPS를 낮춥니다.
쿼리 런타임
max_num_levels K-평균 클러스터링 트리의 최대 수준 수입니다.
  • 2단계 트리 색인: 2단계 트리 기반 양자화에 기본적으로 설정됩니다.
  • 3단계 트리 색인: 3단계 트리 기반 양자화의 경우 명시적으로 2로 설정합니다.
색인 생성

ScaNN 색인 조정

튜닝 매개변수가 설정되는 방법을 보여주는 2단계 및 3단계 ScaNN 색인의 다음 예를 참고하세요.

2단계 색인

SET LOCAL scann.num_leaves_to_search = 1;
SET LOCAL scann.pre_reordering_num_neighbors=50;

CREATE INDEX my-scann-index ON my-table
  USING scann (vector_column cosine)
  WITH (num_leaves = [power(1000000, 1/2)]);

3단계 색인

SET LOCAL scann.num_leaves_to_search = 10;
SET LOCAL scann.pre_reordering_num_neighbors=50;

CREATE INDEX my-scann-index ON my-table
  USING scann (vector_column cosine)
  WITH (num_leaves = [power(1000000, 2/3)], max_num_levels = 2);

ScaNN 색인이 이미 생성된 테이블의 삽입 또는 업데이트 작업은 학습된 트리가 색인을 최적화하는 방식에 영향을 미칩니다. 테이블이 자주 업데이트되거나 삽입되는 경향이 있는 경우 기존 ScaNN 색인을 주기적으로 다시 색인하여 재현율 정확도를 개선하는 것이 좋습니다.

색인 측정항목을 모니터링하여 색인이 빌드된 이후 생성된 변형의 양을 확인한 다음 그에 따라 색인을 다시 생성할 수 있습니다. 측정항목에 관한 자세한 내용은 벡터 색인 측정항목을 참고하세요.

튜닝 권장사항

사용할 ScaNN 색인 유형에 따라 색인 조정 권장사항이 달라집니다. 이 섹션에서는 재현율과 QPS 간의 최적 균형을 위해 색인 매개변수를 조정하는 방법에 관한 권장사항을 제공합니다.

2단계 트리 색인

데이터 세트에 적합한 num_leavesnum_leaves_to_search 값을 찾는 데 도움이 되는 추천을 적용하려면 다음 단계를 따르세요.

  1. 색인화된 테이블의 행 수의 제곱근으로 설정된 num_leaves을 사용하여 ScaNN 색인을 만듭니다.
  2. 목표 재현율 범위(예: 95%)에 도달할 때까지 scann.num_of_leaves_to_search 값을 늘려 테스트 쿼리를 실행합니다. 쿼리 분석에 대한 자세한 내용은 쿼리 분석을 참조하세요.
  3. scann.num_leaves_to_searchnum_leaves 간의 비율을 기록해 둡니다. 이는 후속 단계에서 사용됩니다. 이 비율은 타겟 재현율을 달성하는 데 도움이 되는 데이터 세트에 대한 근사치를 제공합니다.

    고차원 벡터 (500차원 이상)로 작업하고 재현율을 개선하려면 scann.pre_reordering_num_neighbors 값을 조정해 보세요. 시작점으로 K이 쿼리에서 설정한 제한인 경우 값을 100 * sqrt(K)로 설정합니다.
  4. 쿼리가 목표 재현율을 달성한 후 QPS가 너무 낮으면 다음 단계를 따르세요.
    1. 다음 안내에 따라 num_leavesscann.num_leaves_to_search 값을 늘려 색인을 다시 만듭니다.
      • num_leaves를 행 수 제곱근의 더 큰 계수로 설정합니다. 예를 들어 색인의 num_leaves이 행 수의 제곱근으로 설정되어 있으면 제곱근의 두 배로 설정해 보세요. 값이 이미 두 배인 경우 제곱근의 세 배로 설정해 보세요.
      • 3단계에서 기록한 num_leaves과의 비율을 유지하기 위해 필요에 따라 scann.num_leaves_to_search를 늘립니다.
      • num_leaves를 행 수를 100으로 나눈 값 이하로 설정합니다.
    2. 테스트 쿼리를 다시 실행합니다. 테스트 쿼리를 실행하는 동안 scann.num_leaves_to_search를 줄여 실행하면서 재현율을 높게 유지하면서 QPS를 높이는 값을 찾아보세요. 색인을 다시 빌드하지 않고 scann.num_leaves_to_search 값을 다양하게 시도해 보세요.
  5. QPS와 재현율 범위가 모두 허용되는 값에 도달할 때까지 4단계를 반복합니다.

3단계 트리 색인

2단계 트리 ScaNN 색인에 대한 권장사항 외에도 다음 안내와 단계를 사용하여 색인을 조정하세요.

  • 2단계 트리의 경우 1에서 3단계 트리의 경우 2max_num_levels를 늘리면 색인을 만드는 시간이 크게 줄어들지만 재현율 정확도가 떨어집니다. 다음 권장사항을 사용하여 max_num_levels을 설정합니다.
    • 벡터 행 수가 1억 개를 초과하면 값을 2로 설정합니다.
    • 벡터 행 수가 1,000만 행 미만이면 값을 1로 설정합니다.
    • 필요한 색인 생성 시간과 재현율 정확도의 균형에 따라 벡터 행 수가 1, 000만~1억 행인 경우 1 또는 2로 설정합니다.

권장사항을 적용하여 num_leavesmax_num_levels 색인 파라미터의 최적 값을 찾으려면 다음 단계를 따르세요.

  1. 데이터 세트를 기반으로 다음 num_leavesmax_num_levels 조합을 사용하여 ScaNN 색인을 만듭니다.

    • 벡터 행이 1억 개 이상인 경우: max_num_levels2로, num_leavespower(rows, ⅔)로 설정합니다.
    • 벡터 행이 1억 개 미만인 경우: max_num_levels1로, num_leavessqrt(rows)로 설정합니다.
    • 벡터 행이 1,000만~1억 개인 경우: 먼저 max_num_levels1로, num_leavessqrt(rows)로 설정합니다.
  2. 테스트 쿼리를 실행합니다. 쿼리 분석에 대한 자세한 내용은 쿼리 분석을 참조하세요.

    색인 생성 시간이 만족스러우면 max_num_levels 값을 유지하고 num_leaves 값을 실험하여 최적의 재현율 정확도를 확인합니다.

  3. 색인 생성 시간이 만족스럽지 않으면 다음을 수행하세요.

    • max_num_levels 값이 1이면 색인을 삭제합니다. max_num_levels 값이 2으로 설정된 색인을 다시 빌드합니다.

      쿼리를 실행하고 최적의 재현율 정확도를 위해 num_leaves 값을 조정합니다.

    • max_num_levels 값이 2이면 색인을 삭제합니다. 동일한 max_num_levels 값으로 색인을 다시 빌드하고 최적의 재현율 정확도를 위해 num_leaves 값을 조정합니다.

IVF 색인 조정

lists, ivf.probes, quantizer 매개변수에 설정된 값을 조정하면 애플리케이션의 성능을 최적화하는 데 도움이 될 수 있습니다.

조정 매개변수 설명 매개변수 유형
lists 색인 빌드 중에 생성된 목록 수입니다. 이 값을 설정하는 시작점은 최대 100만 행의 경우 (rows)/1000이고 100만 행 초과의 경우 sqrt(rows)입니다. 색인 생성
quantizer K-means 트리에 사용할 양자화기의 유형입니다. 기본값은 쿼리 성능 향상을 위해 SQ8입니다. 더 나은 회상을 위해 FLAT으로 설정합니다. 색인 생성
ivf.probes 검색 중에 탐색할 최근접 목록의 수입니다. 이 값의 시작점은
sqrt(lists)입니다.
쿼리 런타임

튜닝 매개변수가 설정된 IVF 색인을 보여주는 다음 예를 참고하세요.

SET LOCAL ivf.probes = 10;

CREATE INDEX my-ivf-index ON my-table
  USING ivf (vector_column cosine)
  WITH (lists = 100, quantizer = 'SQ8');

IVFFlat 색인 조정

listsivfflat.probes 매개변수에 설정한 값을 조정하면 애플리케이션 성능을 최적화할 수 있습니다.

조정 매개변수 설명 매개변수 유형
lists 색인 빌드 중에 생성된 목록 수입니다. 이 값을 설정하는 시작점은 최대 100만 행의 경우 (rows)/1000이고 100만 행 초과의 경우 sqrt(rows)입니다. 색인 생성
ivfflat.probes 검색 중에 탐색할 최근접 목록의 수입니다. 이 값의 시작점은
sqrt(lists)입니다.
쿼리 런타임

IVFFlat 색인을 빌드하기 전에 데이터베이스의 max_parallel_maintenance_workers 플래그가 대규모 테이블에서 색인 생성을 촉진할 수 있는 충분한 값으로 설정되어 있는지 확인하세요.

튜닝 매개변수가 설정된 IVFFlat 색인을 보여주는 다음 예를 참고하세요.

SET LOCAL ivfflat.probes = 10;

CREATE INDEX my-ivfflat-index ON my-table
  USING ivfflat (vector_column cosine)
  WITH (lists = 100);

HNSW 색인 조정

m, ef_construction, hnsw.ef_search 매개변수에 설정된 값을 조정하면 애플리케이션 성능을 최적화할 수 있습니다.

조정 매개변수 설명 매개변수 유형
m 그래프의 노드에서 연결할 수 있는 최대 연결 수입니다. 기본값인 16(기본값)으로 시작하여 데이터 세트의 크기에 따라 더 높은 값을 실험해 볼 수 있습니다. 색인 생성
ef_construction 그래프 구성 중에 유지되는 동적 후보 목록의 크기입니다. 이 목록은 노드의 최근접 이웃에 대한 현재 최적의 후보를 지속적으로 업데이트합니다. 이 값을 m 값의 두 배보다 큰 값으로 설정합니다(예: 64(기본값)). 색인 생성
ef_search 검색 중에 사용되는 동적 후보 목록의 크기입니다. 이 값을 m 또는 ef_construction로 설정한 다음, 리콜을 관찰하면서 변경할 수 있습니다. 기본값은 40입니다. 쿼리 런타임

튜닝 매개변수가 설정된 hnsw 색인을 보여주는 다음 예를 참고하세요.

SET LOCAL hnsw.ef_search = 40;

CREATE INDEX my-hnsw-index ON my-table
  USING hnsw (vector_column cosine)
  WITH (m = 16, ef_construction = 200);

쿼리 분석

다음 예시 SQL 쿼리와 같이 EXPLAIN ANALYZE 명령어를 사용하여 쿼리 통계를 분석합니다.

  EXPLAIN ANALYZE SELECT result-column FROM my-table
    ORDER BY EMBEDDING_COLUMN ::vector
    USING INDEX my-scann-index
    <-> embedding('textembedding-gecko@003', 'What is a database?')
    LIMIT 1;

예시 응답 QUERY PLAN에는 소요 시간, 스캔되거나 반환된 행 수, 사용된 리소스와 같은 정보가 포함됩니다.

Limit  (cost=0.42..15.27 rows=1 width=32) (actual time=0.106..0.132 rows=1 loops=1)
  ->  Index Scan using my-scann-index on my-table  (cost=0.42..858027.93 rows=100000 width=32) (actual time=0.105..0.129 rows=1 loops=1)
        Order By: (embedding_column <-> embedding('textgecko@003', 'What is a database?')::vector(768))
        Limit value: 1
Planning Time: 0.354 ms
Execution Time: 0.141 ms

벡터 색인 측정항목 보기

벡터 색인 측정항목을 사용하여 벡터 색인의 성능을 검토하고, 개선이 필요한 영역을 파악하고, 필요한 경우 측정항목을 기반으로 색인을 조정할 수 있습니다.

모든 벡터 색인 측정항목을 보려면 pg_stat_ann_indexes 뷰를 사용하는 다음 SQL 쿼리를 실행하세요.

SELECT * FROM pg_stat_ann_indexes;

전체 측정항목 목록에 관한 자세한 내용은 벡터 색인 측정항목을 참고하세요.

다음 단계