ScaNN 색인 만들기

문서 버전을 선택합니다.

저장된 임베딩을 사용하여 ScaNN 벡터 색인을 생성하고 AlloyDB Omni로 임베딩을 쿼리합니다.

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

시작하기 전에

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

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

    비어 있거나 파티션을 나눈 테이블에서 ScaNN 색인을 생성하려 하면 문제가 발생할 수 있습니다. 생성된 오류에 대한 자세한 내용은 ScaNN 색인 오류 문제 해결을 참고하세요. 빈 테이블이나 작은 테이블에 색인을 만들려면 빈 테이블 또는 거의 비어 있는 테이블의 지연된 색인 생성을 참고하세요.

  • vectoralloydb_scann 확장 프로그램이 설치되어 있습니다.

    CREATE EXTENSION IF NOT EXISTS alloydb_scann CASCADE;
    

    alloydb_scann 확장 프로그램을 설치하면 vector 확장 프로그램이 설치되어 있는지 자동으로 확인하고 설치되어 있지 않으면 설치합니다. vector를 별도로 수동으로 설치할 필요가 없습니다.

  • 4단계 ScaNN 색인을 만들려면 먼저 AlloyDB Omni 인스턴스에 프리뷰 기능을 사용 설정해야 합니다. 미리보기 기능을 사용 설정하려면 다음 두 가지 방법 중 하나를 선택하세요.

자동 조정 색인 만들기

자동 조정된 ScaNN 색인을 사용하면 AlloyDB Omni에서 색인 구조를 관리하고 조정하여 색인 생성을 간소화할 수 있습니다. 색인 조정에 대한 세부적인 제어가 필요한 경우 수동으로 조정된 ScaNN 색인을 만드세요.

자동 조정 색인은 다음 두 가지 방법으로 최적화할 수 있습니다.

  • (기본값) 색인 빌드 시간이 길어지는 대신 벡터 검색 재현율과 지연 시간
  • 색인 빌드 시간과 검색 성능의 균형 유지

자동으로 조정된 ScaNN 색인을 만들려면 다음 명령어를 실행합니다.

CREATE INDEX INDEX_NAME ON TABLE
       USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)

다음을 바꿉니다.

  • INDEX_NAME: 만들려는 인덱스의 이름입니다. 예를 들면 my_scann_index입니다. 색인 이름은 데이터베이스 전체에서 공유됩니다. 각 색인 이름이 데이터베이스의 각 테이블에 고유한지 확인합니다.

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

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

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

    • L2 거리: l2

    • 내적: dot_product

    • 코사인 거리: cosine

이 명령어를 사용하면 검색 성능에 최적화된 ScaNN 색인이 생성됩니다. 이 설정을 변경하려면 다음 명령어를 실행하세요.

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: 색인 빌드 시간과 검색 성능의 균형을 맞춥니다.

    OPTIMIZATION가 설정된 경우 MODE='AUTO'도 포함해야 합니다.

수동으로 조정된 색인 만들기

애플리케이션에 재현율 및 색인 빌드 시간에 관한 특정 요구사항이 있는 경우 ScaNN 색인을 수동으로 만들고 조정할 수 있습니다.

저장된 벡터 임베딩이 포함된 열에 ScaNN 색인을 수동으로 만들려면 다음 명령어를 참고하세요.

2단계 트리 색인

CREATE INDEX INDEX_NAME ON TABLE
       USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
WITH (mode='MANUAL',
      num_leaves=NUM_LEAVES_VALUE,
      quantizer=QUANTIZER);
  • INDEX_NAME: 만들려는 색인의 이름입니다. 예를 들면 my_scann_index입니다. 색인 이름은 데이터베이스 전체에서 공유됩니다. 각 색인 이름이 데이터베이스의 각 테이블에 고유해야 합니다.
  • TABLE: 색인을 추가할 테이블
  • EMBEDDING_COLUMN: `vector` 데이터를 저장하는 열입니다.
  • DISTANCE_FUNCTION: 이 색인과 함께 사용할 거리 함수입니다. 다음 중 하나를 선택합니다.
    • L2 거리: l2
    • 내적: dot_product
    • 코사인 거리: cosine
  • NUM_LEAVES_VALUE: 이 색인에 적용할 파티션 수입니다. 1~3천만 사이의 값으로 설정합니다. 이 값을 선택하는 방법에 관한 자세한 내용은 ScaNN 색인 조정을 참고하세요.
  • QUANTIZER: 사용할 양자화기 유형입니다. ScaNN 색인을 열 기반 엔진에 로드하여 벡터 검색을 더욱 가속화할 수 있습니다. 다음 중 하나를 선택합니다.
    • (기본값) SQ8: 재현율 손실을 최소화하면서 균형 잡힌 쿼리 성능을 제공합니다. 일반적으로 1~2% 미만입니다.
    • (미리보기) AH: 비대칭 해싱 (AH)은 SQ8와 비교할 때 최대 4배 압축됩니다. 열 기반 엔진이 사용 설정되고 색인 및 테이블 데이터가 열 기반 엔진에 채워진 경우 쿼리 성능이 향상될 수 있으므로 이를 고려해 보세요. 자세한 내용은 ScaNN 조정 권장사항을 참고하세요.
    • FLAT: 검색 성능이 저하되는 대신 99% 이상의 최고 재현율을 제공합니다.

3단계 트리 색인

CREATE INDEX INDEX_NAME ON TABLE
       USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
WITH (mode='MANUAL',
      num_leaves=NUM_LEAVES_VALUE,
      quantizer=QUANTIZER,
      auto_maintenance=AUTO_MAINTENANCE,
      max_num_levels = 2);
  • INDEX_NAME: 만들려는 색인의 이름입니다. 예를 들면 my_scann_index입니다. 색인 이름은 데이터베이스 전체에서 공유됩니다. 각 색인 이름이 데이터베이스의 각 테이블에 고유해야 합니다.
  • TABLE: 색인을 추가할 테이블
  • EMBEDDING_COLUMN: `vector` 데이터를 저장하는 열입니다.
  • DISTANCE_FUNCTION: 이 색인과 함께 사용할 거리 함수입니다. 다음 중 하나를 선택합니다.
    • L2 거리: l2
    • 내적: dot_product
    • 코사인 거리: cosine
  • NUM_LEAVES_VALUE: 이 색인에 적용할 파티션 수입니다. 1~3천만 사이의 값으로 설정합니다. 이 값을 선택하는 방법에 관한 자세한 내용은 ScaNN 색인 조정을 참고하세요.
  • QUANTIZER: 사용할 양자화기 유형입니다. 벡터 검색을 더욱 가속화하기 위해 ScaNN 색인을 열 기반 엔진에 로드할 수 있습니다. 다음 중 하나를 선택합니다.
    • (기본값) SQ8: 재현율 손실을 최소화하면서 균형 잡힌 쿼리 성능을 제공합니다. 일반적으로 1~2% 미만입니다.
    • (미리보기) AH: 비대칭 해싱 (AH)은 SQ8와 비교할 때 최대 4배 압축됩니다. 열 기반 엔진이 사용 설정되고 색인 및 테이블 데이터가 열 기반 엔진에 채워진 경우 쿼리 성능이 향상될 수 있으므로 이를 고려해 보세요. 자세한 내용은 ScaNN 조정 권장사항을 참고하세요.
    • FLAT: 검색 성능이 저하되는 대신 99% 이상의 최고 재현율을 제공합니다.
  • (선택사항) AUTO_MAINTENANCE: 색인의 자동 유지보수가 사용 설정되었는지 또는 사용 중지되었는지를 제어합니다. 자동 유지보수에 관한 자세한 내용은 벡터 색인 유지보수를 참고하세요.
    • (기본값) ON: AlloyDB Omni가 색인에 대한 자동 유지보수를 실행합니다.
    • OFF: AlloyDB Omni는 색인에 대한 자동 유지 관리를 실행하지 않습니다.
  • max_num_levels = 2: K-평균 클러스터링 트리의 최대 중심 수준 수입니다. 3단계 색인을 만들려면 이 매개변수를 2로 설정합니다.

4단계 트리 색인

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 = 3);
  • INDEX_NAME: 만들려는 색인의 이름입니다. 예를 들면 my_scann_index입니다. 색인 이름은 데이터베이스 전체에서 공유됩니다. 각 색인 이름이 데이터베이스의 각 테이블에 고유해야 합니다.
  • TABLE: 색인을 추가할 테이블
  • EMBEDDING_COLUMN: `vector` 데이터를 저장하는 열입니다.
  • DISTANCE_FUNCTION: 이 색인과 함께 사용할 거리 함수입니다. 다음 중 하나를 선택합니다.
    • L2 거리: l2
    • 내적: dot_product
    • 코사인 거리: cosine
  • NUM_LEAVES_VALUE: 이 색인에 적용할 파티션 수입니다. 1~3천만 사이의 값으로 설정합니다. 이 값을 선택하는 방법에 관한 자세한 내용은 ScaNN 색인 조정을 참고하세요.
  • QUANTIZER: 사용할 양자화기 유형입니다. 벡터 검색을 더욱 가속화하기 위해 ScaNN 색인을 열 기반 엔진에 로드할 수 있습니다. 다음 중 하나를 선택합니다.
    • (기본값) SQ8: 재현율 손실을 최소화하면서 균형 잡힌 쿼리 성능을 제공합니다. 일반적으로 1~2% 미만입니다.
    • 미리보기 AH: 비대칭 해싱 (AH)은 SQ8와 비교했을 때 최대 4배 압축됩니다. 열 기반 엔진이 사용 설정되고 색인 및 테이블 데이터가 열 기반 엔진에 채워진 경우 쿼리 성능이 향상될 수 있으므로 이를 고려해 보세요. 자세한 내용은 ScaNN 조정 권장사항을 참고하세요.
    • FLAT: 검색 성능이 저하되는 대신 99% 이상의 최고 재현율을 제공합니다.
  • max_num_levels = 3: K-평균 클러스터링 트리의 최대 중심 수준 수입니다. 4단계 색인을 만들려면 이 파라미터를 3로 설정합니다.

수동으로 조정된 색인을 자동으로 조정된 색인으로 변환

수동으로 조정된 색인을 자동으로 조정된 색인으로 변환하려면 다음 단계를 완료하세요.

  1. 수동으로 조정된 색인에 정의된 모든 쿼리 매개변수를 재설정합니다.

    ALTER INDEX INDEX_NAME RESET (PARAMETER_NAME);
    

    다음 변수를 바꿉니다.

    • INDEX_NAME: 변환하려는 색인의 이름입니다. 예를 들면 my_scann_index입니다. 색인 이름은 데이터베이스 전체에서 공유됩니다. 각 색인 이름이 데이터베이스의 각 테이블에 고유한지 확인합니다.

    • PARAMETER_NAME: 재설정할 쿼리 매개변수의 이름이 포함된 쉼표로 구분된 목록입니다. 예를 들면 num_leaves, quantization입니다.

      num_leaves을 재설정하기 전에 다른 모든 쿼리 매개변수를 재설정해야 합니다.

  2. 수동으로 조정된 색인을 다시 색인하여 자동으로 조정된 색인으로 변환합니다.

    REINDEX INDEX CONCURRENTLY INDEX_NAME;
    

real[] 데이터 유형의 ScaNN 색인 만들기

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

CREATE INDEX INDEX_NAME ON TABLE
USING scann (CAST(EMBEDDING_COLUMN AS vector(DIMENSIONS)) DISTANCE_FUNCTION)

다음을 바꿉니다.

  • INDEX_NAME: 만들려는 인덱스의 이름입니다. 예를 들면 my_scann_index입니다. 색인 이름은 데이터베이스 전체에서 공유됩니다. 각 색인 이름이 데이터베이스의 각 테이블에 고유한지 확인합니다.

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

  • DIMENSIONS: 모델에서 지원하는 차원 수입니다.

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

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

    • L2 거리: l2

    • 내적: dot_product

    • 코사인 거리: cosine

색인 생성 진행 상황 보기

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

SELECT * FROM pg_stat_progress_create_index;

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

빈 테이블 또는 행이 부족한 테이블의 지연된 색인 만들기

기본적으로 비어 있거나 num_leaves 색인 옵션 값보다 행이 적은 테이블에는 ScaNN 색인을 만들 수 없습니다.

이 제한을 우회하려면 지연된 색인 생성을 사용 설정하여 AlloyDB Omni가 테이블의 행 수가 num_leaves에서 정의한 임계값에 도달할 때까지 색인 생성을 지연하도록 합니다. 기준이 충족되면 AlloyDB Omni가 백그라운드에서 색인 빌드를 시작합니다.

이 지연된 작업은 차단되지 않는 프로세스이므로 읽기 및 쓰기와 같은 다른 데이터베이스 작업이 중단 없이 계속될 수 있습니다. 색인 재빌드는 백그라운드에서 발생하므로 테이블이 소규모 배치로 데이터 행을 수집하는 경우 지연된 색인 생성이 적합합니다. 행 수가 기준점에 도달하면 색인 재빌드가 자동으로 트리거됩니다.

하지만 단일 트랜잭션에서 테이블에 많은 수의 행을 삽입할 계획이라면 트랜잭션을 여러 트랜잭션으로 분할하거나 지연된 색인 생성을 사용 설정하지 않고 ScaNN 색인을 생성하는 것이 좋습니다.

지연된 색인 생성 사용 설정

지연된 색인 생성을 사용 설정하려면 다음 단계를 따르세요.

  1. scann.enable_index_maintenance 플래그와 다음 플래그 중 하나가 사용 설정되어 있는지 확인합니다.

    사용량을 구성하려면 gcloud CLI를 사용하세요.

    • 지연된 색인 생성과 기타 미리보기 기능을 사용 설정하려면 다음 단계를 따르세요.

      gcloud alloydb instances update INSTANCE_ID \
         --database-flags scann.enable_index_maintenance=on \
         --database-flags scann.enable_preview_features=on \
         --region=REGION_ID \
         --cluster=CLUSTER_ID \
         --project=PROJECT_ID
      
    • 다른 미리보기 기능을 사용 설정하지 않고 지연된 색인 생성을 명시적으로 사용 설정하려면 다음을 실행하세요.

      gcloud alloydb instances update INSTANCE_ID \
         --database-flags scann.enable_index_maintenance=on \
         --database-flags scann.enable_index_with_insufficient_data=on \
         --region=REGION_ID \
         --cluster=CLUSTER_ID \
         --project=PROJECT_ID
      

    다음을 바꿉니다.

    • INSTANCE_ID: 인스턴스의 ID
    • REGION_ID: 인스턴스가 배치된 리전(예: us-central1)
    • CLUSTER_ID: 인스턴스가 배치된 클러스터의 ID
    • PROJECT_ID: 클러스터가 배치된 프로젝트의 ID
  2. ScaNN 색인을 만듭니다. 수동 모드에서 색인을 만드는 경우 auto_maintenance 매개변수가 on로 설정되어 있는지 확인합니다. 자세한 내용은 수동으로 조정된 색인 만들기를 참고하세요.

제한사항

  • 자동 색인 생성 백그라운드 프로세스는 데이터베이스 수준 플래그 값을 사용합니다. SET LOCAL 명령어를 사용하여 세션 수준 플래그를 설정하더라도 프로세스에서는 데이터베이스 수준에서 설정된 플래그 값을 고려합니다.
  • 단일 트랜잭션에서 빈 테이블에 많은 양의 데이터를 일괄 삽입하려는 경우 단일 삽입 트랜잭션을 실행한 후 ScaNN 색인을 만드는 것이 좋습니다.

빈 테이블 또는 작은 테이블에서 색인 강제 생성

AlloyDB Omni는 다음과 같은 이유로 빈 테이블이나 행 수가 매우 적은 테이블에 ScaNN 색인이 생성되지 않도록 유효성 검사를 사용합니다.

  • ScaNN 색인이 불충분한 데이터로 학습됩니다. 이로 인해 벡터 유사성 검색의 재현율이 낮아질 수 있습니다.

  • 데이터베이스에 대한 쓰기 성능이 저하될 수 있습니다.

성능이 최적화되지 않은 경우 색인 생성을 지연하는 것이 좋습니다.

하지만 일부 개발 시나리오나 테스트 시나리오에서는 비어 있거나 작은 테이블에 색인을 만들어야 할 수 있습니다. 이러한 경우 강제로 색인을 생성할 수 있습니다. 색인 생성을 강제하려면 SUPERUSER 권한이 필요합니다.

색인 생성을 강제하려면 다음 단계를 완료하세요.

  1. 데이터베이스에서 scann.allow_blocked_operations 세션 수준 파라미터를 true로 설정합니다.

    SET scann.allow_blocked_operations = true;
    
  2. 이러한 쿼리를 실행하는 데 사용하는 사용자에게 SUPERUSER 권한이 없는 경우 권한을 할당합니다.

    CREATE USER USERNAME WITH SUPERUSER PASSWORD PASSWORD;
    

    다음 변수를 바꿉니다.

    • USERNAME: SUPERUSER 권한을 부여하려는 사용자의 이름입니다.
    • PASSWORD: 사용자의 비밀번호입니다.

동시에 색인 빌드

색인을 더 빠르게 빌드하기 위해 AlloyDB Omni에서 데이터 세트와 선택한 색인 유형에 따라 여러 동시 작업자를 자동으로 생성할 수 있습니다. 이는 3단계 또는 4단계 ScaNN 색인을 만들거나 데이터 세트가 1억 행을 초과하는 경우에 트리거되는 경우가 많습니다.

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

ScaNN 색인을 만들 때 메모리 부족 문제가 발생하지 않도록 maintenance_work_memshared_buffers 데이터베이스 플래그가 총 머신 메모리보다 작은 값으로 설정되도록 유의하세요.

쿼리 실행

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

텍스트 문자열의 의미론적 최근접 이웃을 찾으려면 google_ml.embedding() 함수를 사용하여 텍스트를 벡터로 변환하면 됩니다.

google_ml.embedding()에서 실제 배열을 반환하므로 근접 이웃 연산자(예: L2 거리의 경우 <->)에 적용하기 전에 함수 호출을 vector로 명시적으로 변환해야 합니다. 그러면 이러한 연산자가 ScaNN 색인을 사용하여 의미상 가장 유사한 임베딩이 있는 데이터베이스 행을 찾을 수 있습니다.

SELECT * FROM TABLE
ORDER BY EMBEDDING_COLUMN DISTANCE_FUNCTION_QUERY
  google_ml.embedding(
      model_id => 'MODEL_ID',
      content => 'CONTENT')::vector
LIMIT ROW_COUNT

다음 변수를 바꿉니다.

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

  • EMBEDDING_COLUMN: 저장된 임베딩이 포함된 열입니다.

  • DISTANCE_FUNCTION_QUERY: 이 쿼리와 함께 사용할 거리 함수입니다. 색인을 만들 때 사용한 거리 함수에 해당하는 쿼리를 선택합니다.

    • L2 거리: <->

    • 내적: <#>

    • 코사인 거리: <=>

  • MODEL_ID: 사용할 등록된 임베딩 모델의 ID입니다.

  • CONTENT: 임베딩으로 변환하여 검색할 텍스트 문자열입니다.

  • ROW_COUNT: 반환할 행 수입니다. 예를 들어 가장 일치하는 값 하나만 원하는 경우 1을 지정합니다.

다음 단계