ScaNN 색인 만들기

이 페이지에서는 저장된 임베딩을 사용하여 색인을 생성하고 PostgreSQL용 AlloyDB에서 ScaNN 색인을 사용하여 임베딩을 쿼리하는 방법을 설명합니다. 임베딩 저장에 대한 자세한 내용은 벡터 임베딩 저장을 참고하세요.

AlloyDB alloydb_scann: ScaNN 알고리즘으로 구동되는 매우 효율적인 최근접 이웃 색인을 구현하는 Google에서 개발한 PostgreSQL 확장 프로그램입니다.

ScaNN 색인은 근사 최근접 이웃 검색을 위한 트리 기반 양자화 색인입니다. HNSW에 비해 색인 빌드 시간이 짧고 메모리 사용량이 적습니다. 또한 워크로드에 따라 HNSW에 비해 더 빠른 QPS를 제공합니다.

시작하기 전에

색인 생성을 시작하려면 다음 기본 요건을 완료해야 합니다.

  • AlloyDB 데이터베이스의 테이블에 임베딩 벡터를 추가해야 합니다.

  • Google에서 AlloyDB용으로 확장한 pgvector 기반 vector 확장 프로그램과 alloydb_scann 확장 프로그램이 설치되어 있습니다.

    CREATE EXTENSION IF NOT EXISTS alloydb_scann CASCADE;
    
  • 자동으로 조정된 ScaNN 색인을 만들려면 scann.enable_preview_features 플래그가 사용 설정되어 있는지 확인합니다. 미리보기 기능을 사용 설정하지 않으려는 경우 또는 프로덕션 인스턴스의 경우 대신 특정 매개변수로 ScaNN 색인을 만들면 됩니다.

자동으로 조정된 ScaNN 색인 만들기

자동 색인 기능을 사용하면 색인 생성을 간소화하여 검색 성능에 최적화된 색인 또는 균형 잡힌 색인 빌드 시간과 검색 성능을 자동으로 만들 수 있습니다.

AUTO 모드를 사용하는 경우 테이블 이름과 임베딩 열, 사용할 거리 함수만 지정하면 됩니다. 검색 성능을 위해 색인을 최적화하거나 색인 빌드 시간과 검색 성능 간의 균형을 맞출 수 있습니다.

MANUAL 모드를 사용하여 다른 색인 조정 매개변수를 세부적으로 제어하는 색인을 만드는 옵션도 있습니다.

AUTO 모드에서 ScaNN 색인 만들기

AUTO 모드에서 색인을 만들기 전에 유의해야 할 사항은 다음과 같습니다.

  • 데이터가 부족한 테이블에는 AlloyDB에서 ScaNN 색인을 만들 수 없습니다.
  • AUTO 모드에서 색인을 만들 때는 num_leaves와 같은 색인 생성 매개변수를 설정할 수 없습니다.
  • AUTO 모드에서 생성된 모든 색인에 대해 기본적으로 자동 유지관리가 사용 설정됩니다.

AUTO 모드에서 색인을 만들려면 다음 명령어를 실행합니다.

      CREATE INDEX INDEX_NAME ON TABLE \
      USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION) \
      WITH (mode=AUTO', optimization='OPTIMIZATION');

다음을 바꿉니다.

  • INDEX_NAME: 만들려는 색인의 이름(예: my-scann-index) 색인 이름은 데이터베이스 전체에서 공유됩니다. 각 색인 이름이 데이터베이스의 각 테이블에 고유한지 확인합니다.

  • TABLE: 색인을 추가할 테이블

  • EMBEDDING_COLUMN: vector 데이터를 저장하는 열

  • DISTANCE_FUNCTION: 이 색인과 함께 사용할 거리 함수입니다. 다음 중 하나를 선택합니다.

    • L2 거리: l2

    • 내적: dot_product

    • 코사인 거리: cosine

  • OPTIMIZATION: 다음 중 하나로 설정합니다.

    • SEARCH_OPTIMIZED: 색인 빌드 시간이 길어지는 대신 벡터 검색 재현율과 벡터 검색 지연 시간을 모두 최적화합니다.
    • BALANCED: 색인 빌드 시간과 검색 성능의 균형을 맞추는 색인을 만듭니다.

MANUAL 모드에서 ScaNN 색인 만들기

scann.enable_preview_features 플래그를 사용 설정했고 조정 매개변수를 세밀하게 제어하려면 MANUAL 모드에서 색인을 만들면 됩니다.

MANUAL 모드에서 ScaNN 색인을 만들려면 다음 명령어를 실행합니다.

      CREATE INDEX INDEX_NAME ON TABLE \
      USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION) \
      WITH (mode='MANUAL, num_leaves=NUM_LEAVES_VALUE, [quantizer =QUANTIZER, max_num_levels=MAX_NUM_LEVELS]);

다음을 바꿉니다.

  • INDEX_NAME: 만들려는 색인의 이름(예: my-scann-index) 색인 이름은 데이터베이스 전체에서 공유됩니다. 각 색인 이름이 데이터베이스의 각 테이블에 고유한지 확인합니다.

  • TABLE: 색인을 추가할 테이블

  • EMBEDDING_COLUMN: vector 데이터를 저장하는 열

  • DISTANCE_FUNCTION: 이 색인과 함께 사용할 거리 함수입니다. 다음 중 하나를 선택합니다.

    • L2 거리: l2

    • 내적: dot_product

    • 코사인 거리: cosine

  • NUM_LEAVES_VALUE: 이 색인에 적용할 파티션 수입니다. 1~1048576 사이의 값으로 설정합니다.

  • QUANTIZER: K-평균 트리에서 사용할 양자화기 유형입니다. 기본값은 SQ8로 설정되어 있으며, 이를 통해 재현율 손실을 최소화하면서 (일반적으로 1~2% 미만) 쿼리 성능을 개선할 수 있습니다. 99% 이상의 재현율을 위해 FLAT으로 설정할 수도 있습니다.

  • MAX_NUM_LEVELS: K-평균 클러스터링 트리의 최대 수준 수. 2단계 트리 기반 양자화의 경우 1(기본값)로 설정하고 3단계 트리 기반 양자화의 경우 2로 설정합니다.

다른 색인 생성 또는 쿼리 런타임 매개변수를 추가하여 색인을 조정할 수 있습니다. 자세한 내용은 ScaNN 색인 조정을 참고하세요.

기존 색인의 모드 변경

AUTO 모드를 사용하여 ScaNN 색인을 만들었고 색인을 수동으로 조정하려면 모드를 MANUAL로 변경해야 합니다.

모드를 MANUAL로 변경하려면 다음 단계를 따르세요.

  1. 모드를 MANUAL로 설정하도록 색인을 업데이트합니다.

    ALTER INDEX INDEX_NAME SET (mode = 'MANUAL', num_leaves = NUM_LEAVES_VALUE);
    

    다음을 바꿉니다.

    • INDEX_NAME: 만들려는 색인의 이름(예: my-scann-index). 색인 이름은 데이터베이스 전체에서 공유됩니다. 각 색인 이름이 데이터베이스의 각 테이블에 고유한지 확인합니다.

    • NUM_LEAVES_VALUE: 이 색인에 적용할 파티션 수. 1~1048576 사이의 값으로 설정합니다.

    다른 색인 생성 또는 쿼리 런타임 매개변수를 추가하여 색인을 조정할 수 있습니다. 자세한 내용은 ScaNN 색인 조정을 참고하세요.

  2. 매개변수를 적용하려면 색인을 다시 빌드하세요.

    REINDEX INDEX CONCURRENTLY INDEX_NAME;
    

모드를 AUTO로 변경하려면 다음 단계를 완료하세요.

  1. 모드를 AUTO로 설정하도록 색인을 업데이트합니다.

    ALTER INDEX INDEX_NAME SET (mode = 'AUTO');
    
  2. 매개변수를 적용하려면 색인을 다시 빌드하세요.

    REINDEX INDEX CONCURRENTLY INDEX_NAME;
    

특정 매개변수로 ScaNN 색인 만들기

애플리케이션에 리콜 및 색인 빌드 시간에 관한 특정 요구사항이 있는 경우 색인을 수동으로 만들 수 있습니다. 워크로드에 따라 2단계 또는 3단계 트리 색인을 만들 수 있습니다. 매개변수 조정에 관한 자세한 내용은 ScaNN 색인 조정을 참고하세요.

2단계 트리 색인

ScaNN 알고리즘을 사용하여 저장된 벡터 임베딩이 포함된 열에 2단계 트리 색인을 적용하려면 다음 DDL 쿼리를 실행하세요.

CREATE INDEX INDEX_NAME ON TABLE
  USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE);

다음을 바꿉니다.

  • INDEX_NAME: 만들려는 색인의 이름(예: my-scann-index). 색인 이름은 데이터베이스 전체에서 공유됩니다. 각 색인 이름이 데이터베이스의 각 테이블에 고유해야 합니다.

  • TABLE: 색인을 추가할 테이블

  • EMBEDDING_COLUMN: vector 데이터를 저장하는 열

  • DISTANCE_FUNCTION: 이 색인과 함께 사용할 거리 함수. 다음 중 하나를 선택합니다.

    • L2 거리: l2

    • 내적: dot_product

    • 코사인 거리: cosine

  • NUM_LEAVES_VALUE: 이 색인에 적용할 파티션 수. 1~1048576 사이의 값으로 설정합니다. 이 값을 결정하는 방법에 관한 자세한 내용은 ScaNN 색인 조정을 참조하세요.

3단계 트리 색인

ScaNN 알고리즘을 사용하여 저장된 벡터 임베딩이 포함된 열에 3단계 트리 색인을 만들려면 다음 DDL 쿼리를 실행하세요.

CREATE INDEX INDEX_NAME ON TABLE
  USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE, max_num_levels = 2);

색인을 만든 후 지정된 텍스트로 최근접 이웃 쿼리 작성의 안내에 따라 색인을 사용하는 최근접 이웃 검색어를 실행할 수 있습니다.

색인 파라미터는 QPS와 재현율 간의 적절한 균형을 유지하도록 설정해야 합니다. ScaNN 색인 조정에 관한 자세한 내용은 ScaNN 색인 조정을 참조하세요.

vector 대신 real[] 데이터 유형을 사용하는 임베딩 열에 이 색인을 만들려면 열을 vector 데이터 유형으로 변환합니다.

CREATE INDEX INDEX_NAME ON TABLE
  USING scann (CAST(EMBEDDING_COLUMN AS vector(DIMENSIONS)) DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE, max_num_levels = MAX_NUM_LEVELS);

DIMENSIONS를 임베딩 열의 차원 너비로 바꿉니다. 차원을 찾는 방법에 대한 자세한 내용은 벡터 함수vector_dims 함수를 참조하세요.

일관된 검색 환경을 구현하려면 ScaNN 색인을 만들 때 자동 유지보수를 사용 설정합니다. 자세한 내용은 벡터 색인 유지보수를 참조하세요. 이 기능은 미리보기 상태로 제공됩니다.

색인 생성 진행 상황을 보려면 pg_stat_progress_create_index 뷰를 사용하세요.

SELECT * FROM pg_stat_progress_create_index;

phase 열에는 현재 색인 생성 상태가 표시됩니다. 색인 빌드 단계가 완료되면 색인 행이 표시되지 않습니다.

평균 재현율과 QPS 균형을 위해 색인을 조정하려면 ScaNN 색인 조정을 참고하세요.

동시에 색인 빌드

색인을 더 빠르게 빌드하기 위해 AlloyDB에서 데이터 세트와 선택한 색인 유형에 따라 여러 동시 작업자를 자동으로 생성할 수 있습니다.

동시 색인 빌드는 3단계 ScaNN 색인을 만들거나 데이터 세트가 1억 행을 초과하는 경우에 트리거되는 경우가 많습니다.

AlloyDB는 동시 작업자 수를 자동으로 최적화하지만 max_parallel_maintenance_workers, max_parallel_workers, min_parallel_table_scan_size PostgreSQL 쿼리 계획 파라미터를 사용하여 동시 작업자를 조정할 수 있습니다.

쿼리 실행

데이터베이스에 임베딩을 저장하고 색인을 생성한 후 데이터를 쿼리할 수 있습니다. alloydb_scann 확장 프로그램으로는 대량 검색어를 실행할 수 없습니다.

임베딩 벡터의 의미론적 최근접 이웃을 찾으려면 색인 생성 중에 사용한 것과 동일한 거리 함수를 설정하는 다음 예시 쿼리를 실행하면 됩니다.

  SELECT * FROM TABLE
    ORDER BY EMBEDDING_COLUMN DISTANCE_FUNCTION_QUERY ['EMBEDDING']
    LIMIT ROW_COUNT

다음을 바꿉니다.

  • TABLE: 텍스트를 비교할 임베딩이 포함된 테이블

  • INDEX_NAME: 사용할 색인의 이름(예: my-scann-index)

  • EMBEDDING_COLUMN: 저장된 임베딩이 포함된 열

  • DISTANCE_FUNCTION_QUERY: 이 쿼리와 함께 사용할 거리 함수. 색인을 만들 때 사용한 거리 함수에 따라 다음 중 하나를 선택합니다.

    • L2 거리: <->

    • 내적: <#>

    • 코사인 거리: <=>

  • EMBEDDING: 의미론적으로 최근접으로 저장된 이웃을 찾으려는 임베딩 벡터

  • ROW_COUNT: 반환할 행의 개수.

    가장 일치하는 값 하나만 원하면 1을 지정합니다.

embedding() 함수를 사용해 텍스트를 벡터로 변환할 수도 있습니다. embedding()에서 real 배열을 반환하므로 가장 가까운 이웃 연산자 (예:embedding()vector <->(L2 거리의 경우) 그러면 이러한 연산자가 ScaNN 색인을 사용하여 의미상 가장 유사한 임베딩이 있는 데이터베이스 행을 찾을 수 있습니다.

다음 단계