벡터 색인 관리

이 기능에 대한 의견을 제공하거나 지원을 요청하려면 bq-vector-search@google.com으로 이메일을 보내 주세요.

이 문서에서는 벡터 색인을 만들고 관리하는 방법을 설명합니다.

벡터 색인은 VECTOR_SEARCH 함수가 임베딩의 벡터 검색을 더 효율적으로 수행할 수 있도록 설계된 데이터 구조입니다. VECTOR_SEARCH가 벡터 색인을 사용할 수 있게 되면 이 함수에서 근사 최근접 이웃 검색 기법을 사용하여 재현율을 줄이는 대신 검색 성능을 향상시켜 더 나은 근사치의 결과를 반환합니다.

역할 및 권한

벡터 색인을 만들려면 색인을 만들 테이블에 대한 bigquery.tables.createIndex IAM 권한이 필요합니다. 벡터 색인을 삭제하려면 bigquery.tables.deleteIndex 권한이 필요합니다. 다음과 같은 사전 정의된 각 IAM 역할에는 벡터 색인을 사용하는 데 필요한 권한이 포함되어 있습니다.

  • BigQuery 데이터 소유자(roles/bigquery.dataOwner)
  • BigQuery 데이터 편집자(roles/bigquery.dataEditor)

벡터 색인 만들기

벡터 색인을 만들려면 CREATE VECTOR INDEX 데이터 정의 언어(DDL) 문을 사용합니다.

  1. BigQuery 페이지로 이동합니다.

    BigQuery로 이동

  2. 쿼리 편집기에서 다음 SQL 문을 실행합니다.

    CREATE [ OR REPLACE ] VECTOR INDEX [ IF NOT EXISTS ] INDEX_NAME
    ON DATASET_NAME.TABLE_NAME(COLUMN_NAME)
    OPTIONS(index_type = INDEX_TYPE,
      distance_type = DISTANCE_TYPE,
      ivf_options = '{"num_lists":NUM_LISTS}')
    

    다음을 바꿉니다.

    • INDEX_NAME: 만들려는 벡터 색인의 이름입니다. 색인은 항상 기본 테이블과 동일한 프로젝트 및 데이터 세트에 생성되므로 이름에 이를 지정할 필요가 없습니다.
    • DATASET_NAME: 테이블이 포함된 데이터 세트의 이름입니다.
    • TABLE_NAME: 임베딩 데이터가 있는 열이 포함된 테이블의 이름입니다.
    • COLUMN_NAME: 임베딩 데이터가 포함된 열의 이름입니다. 이 열의 유형은 ARRAY<FLOAT64>여야 합니다. 이 열에는 하위 필드를 포함할 수 없습니다. 배열의 모든 요소는 NULL이 아니어야 하고 열의 모든 값은 배열 차원이 동일해야 합니다.
    • INDEX_TYPE: 벡터 색인을 빌드하는 데 사용할 알고리즘입니다. 유일하게 지원되는 값은 IVF입니다. IVF를 지정하면 벡터 색인이 역방향 파일 색인(IVF)으로 빌드됩니다. ICF는 k-평균 알고리즘을 사용하여 벡터 데이터를 클러스터링한 다음 이러한 클러스터를 기반으로 벡터 데이터를 파티셔닝합니다. VECTOR_SEARCH 함수를 사용하여 벡터 데이터를 검색할 때 ICF에서 이러한 파티션을 사용해 결과를 결정하기 위해 읽어야 할 데이터의 양을 줄일 수 있습니다.
    • DISTANCE_TYPE: 이 색인을 사용하여 벡터 검색을 수행할 때 사용할 기본 거리 유형을 지정합니다. 지원되는 값은 EUCLIDEANCOSINE입니다. 기본값은 EUCLIDEAN입니다.

      색인 생성 자체는 항상 학습에 EUCLIDEAN 거리를 사용하지만 VECTOR_SEARCH 함수에서 사용되는 거리는 다를 수 있습니다.

      VECTOR_SEARCH 함수의 distance_type 인수 값을 지정하면 DISTANCE_TYPE 값 대신 해당 값이 사용됩니다.

    • NUM_LISTS: IVF 알고리즘이 만드는 목록 수를 결정하는 5,000 이하의 INT64 값입니다. IVF 알고리즘은 전체 데이터 공간을 NUM_LISTS와 동일한 여러 목록으로 나눕니다. 데이터 포인트가 서로 가까울수록 동일한 목록에 배치될 가능성이 높습니다. NUM_LISTS가 작으면 데이터 포인트가 많은 목록이 줄어들고 값이 클수록 데이터 포인트가 적은 목록이 늘어납니다.

      VECTOR_SEARCH 함수의 fraction_lists_to_search 인수와 함께 NUM_LISTS를 사용하여 효율적인 벡터 검색을 만들 수 있습니다. 임베딩 공간에서 많은 작은 그룹에 데이터가 분산되어 있는 경우 높은 NUM_LISTS를 지정하여 더 많은 목록이 있는 색인을 만들고 더 낮은 fraction_lists_to_search 값을 지정하여 벡터 검색에서 더 적은 목록을 스캔합니다. 데이터가 더 적고 큰 그룹에 분산되어 있을 때는 낮은 NUM_LISTS 값과 높은 fraction_lists_to_search 값을 사용합니다. 높은 num_lists 값을 사용하면 벡터 색인을 빌드하는 데 시간이 더 오래 걸릴 수 있습니다.

      NUM_LISTS를 지정하지 않으면 BigQuery가 적절한 값을 계산합니다.

다음 예시에서는 my_tableembedding 열에 벡터 색인을 만듭니다.

CREATE TABLE my_dataset.my_table(embedding ARRAY<FLOAT64>);

CREATE VECTOR INDEX my_index ON my_dataset.my_table(embedding)
OPTIONS(index_type = 'IVF');

다음 예시에서는 my_tableembedding 열에 벡터 색인을 만들고 사용할 거리 유형과 IVF 옵션을 지정합니다.

CREATE TABLE my_dataset.my_table(embedding ARRAY<FLOAT64>);

CREATE VECTOR INDEX my_index ON my_dataset.my_table(embedding)
OPTIONS(index_type = 'IVF', distance_type = 'COSINE',
ivf_options = '{"num_lists": 2500}')

색인 새로고침 이해하기

벡터 색인은 BigQuery에서 완전하게 관리되며 색인 생성된 테이블이 변경되면 자동으로 새로고침됩니다. 테이블에서 색인이 생성된 열을 삭제하거나 테이블 자체의 이름을 바꾸면 벡터 색인이 자동으로 삭제됩니다.

10MB보다 작은 테이블에 벡터 색인을 만들 경우 벡터 색인이 채워지지 않습니다. 마찬가지로 색인이 생성된 테이블에서 데이터를 삭제하고 테이블 크기가 10MB 미만이 되면 벡터 색인이 일시적으로 사용 중지됩니다. 이 경우 벡터 검색 쿼리는 색인을 사용하지 않으며 Job 리소스의 vectorSearchStatistics 섹션에 있는 indexUnusedReasons 코드가 BASE_TABLE_TOO_SMALL입니다. 색인이 없으면 VECTOR_SEARCH는 무작위 대입을 사용해 임베딩의 최근접 이웃을 찾도록 자동으로 되돌아갑니다.

VECTOR_SEARCH 함수를 사용하는 쿼리는 데이터 중 일부가 아직 색인으로 생성되지 않았더라도 항상 올바른 결과를 반환합니다.

벡터 색인 정보 가져오기

INFORMATION_SCHEMA를 쿼리하여 벡터 색인의 존재 및 준비 여부를 확인할 수 있습니다. 다음 뷰에는 벡터 색인의 메타데이터가 포함되어 있습니다.

  • INFORMATION_SCHEMA.VECTOR_INDEXES에는 데이터 세트의 벡터 색인에 대한 정보가 있습니다.

    CREATE VECTOR INDEX 문이 완료된 후에도 색인을 사용하려면 여전히 색인을 채워야 합니다. last_refresh_timecoverage_percentage 열을 사용하여 벡터 색인의 준비 상태를 확인할 수 있습니다. 벡터 색인이 준비되지 않은 경우에도 테이블에서 VECTOR_SEARCH 함수를 사용할 수 있으며, 색인이 없으면 더 느리게 실행될 수 있습니다.

  • INFORMATION_SCHEMA.VECTOR_INDEX_COLUMNS에는 데이터 세트에 있는 모든 테이블의 벡터 색인 생성 열에 대한 정보가 있습니다.

  • INFORMATION_SCHEMA.VECTOR_INDEX_OPTIONS에는 데이터 세트의 벡터 색인에서 사용하는 옵션에 대한 정보가 있습니다.

벡터 색인 예시

다음 예시는 my_project 프로젝트에 위치한 데이터 세트 my_dataset에 있는 테이블의 모든 활성 벡터 색인을 보여줍니다. 여기에는 이름, 벡터 색인을 만드는 데 사용된 DDL 문, 적용 범위 비율이 포함됩니다. 색인이 생성된 기본 테이블이 10MB 미만이면 색인이 채워지지 않으며, 이 경우 coverage_percentage 값은 0입니다.

SELECT table_name, index_name, ddl, coverage_percentage
FROM my_project.my_dataset.INFORMATION_SCHEMA.VECTOR_INDEXES
WHERE index_status = 'ACTIVE';

결과는 다음과 비슷합니다.

+-------------+-------------+-----------------------------------------------------------------------------------------------+---------------------+
| table_name  | index_name  | ddl                                                                                           | coverage_percentage |
+-------------+-------------+-----------------------------------------------------------------------------------------------+---------------------+
| small_table | myindex1    | CREATE VECTOR INDEX `myindex1` ON `my_project.my_dataset.small_table`(embeddings)             | 100                 |
|             |             | OPTIONS (distance_type = 'EUCLIDEAN', index_type = 'IVF', ivf_options = '{"numLists": 3}')    |                     |
+-------------+-------------+-----------------------------------------------------------------------------------------------+---------------------+
| large_table | myindex2    | CREATE VECTOR INDEX `myindex2` ON `my_project.my_dataset.large_table`(vectors)                |  42                 |
|             |             | OPTIONS (distance_type = 'EUCLIDEAN', index_type = 'IVF', ivf_options = '{"numLists": 12}')   |                     |
+-------------+-------------+-----------------------------------------------------------------------------------------------+---------------------+

벡터 색인 열 예시

다음 쿼리는 벡터 색인이 있는 열에 대한 정보를 추출합니다.

SELECT table_name, index_name, index_column_name, index_field_path
FROM my_project.dataset.INFORMATION_SCHEMA.VECTOR_INDEX_COLUMNS;

결과는 다음과 비슷합니다.

+------------+------------+-------------------+------------------+
| table_name | index_name | index_column_name | index_field_path |
+------------+------------+-------------------+------------------+
| table1     | indexa     | a                 | a                |
| table2     | indexb     | b                 | b                |
| table3     | indexc     | c                 | c                |
+------------+------------+-------------------+------------------+

벡터 색인 옵션 예시

다음 쿼리는 벡터 색인 옵션에 대한 정보를 추출합니다.

SELECT table_name, index_name, option_name, option_type, option_value
FROM my_project.dataset.INFORMATION_SCHEMA.VECTOR_INDEX_OPTIONS;

결과는 다음과 비슷합니다.

+------------+------------+------------------+------------------+--------------------+
| table_name | index_name | option_name      | option_type      | option_value       |
+------------+------------+------------------+------------------+--------------------+
| table1     | indexa     | distance_type    | STRING           | EUCLIDEAN          |
| table1     | indexa     | index_type       | STRING           | IVF                |
| table2     | indexb     | ivf_options      | STRING           | {"num_lists": 100} |
| table2     | indexb     | index_type       | STRING           | IVF                |
+------------+------------+------------------+------------------+--------------------+

벡터 색인 사용

벡터 색인 사용에 대한 정보는 벡터 검색어를 실행한 작업의 작업 메타데이터에서 확인할 수 있습니다. Google Cloud 콘솔, bq 명령줄 도구, BigQuery API, 클라이언트 라이브러리를 사용하여 작업 메타데이터를 확인할 수 있습니다.

Google Cloud 콘솔을 사용할 때 벡터 색인 사용 모드벡터 색인 미사용 이유 필드에서 벡터 색인 사용 정보를 찾을 수 있습니다.

bq 도구 또는 BigQuery API를 사용하는 경우 Job 리소스의 VectorSearchStatistics 섹션에서 벡터 색인 사용 정보를 찾을 수 있습니다.

색인 사용 모드는 다음 값 중 하나를 제공하여 벡터 색인이 사용되었는지 여부를 나타냅니다.

  • UNUSED: 사용된 벡터 색인이 없습니다.
  • PARTIALLY_USED: 쿼리의 일부 VECTOR_SEARCH 함수에 벡터 색인이 사용되었고 일부는 사용하지 않았습니다.
  • FULLY_USED: 쿼리의 모든 VECTOR_SEARCH 함수에 벡터 색인이 사용되었습니다.

색인 사용 모드 값이 UNUSED 또는 PARTIALLY_USED인 경우 색인 미사용 이유에서 쿼리에 벡터 색인이 사용되지 않은 이유를 나타냅니다.

예를 들어 bq show --format=prettyjson -j my_job_id에서 반환된 다음 결과는 VECTOR_SEARCH 함수에 use_brute_force 옵션이 지정되었으므로 색인이 사용되지 않았음을 보여줍니다.

"vectorSearchStatistics": {
  "indexUnusedReasons": [
    {
      "baseTable": {
        "datasetId": "my_dataset",
        "projectId": "my_project",
        "tableId": "my_table"
      },
      "code": "INDEX_SUPPRESSED_BY_FUNCTION_OPTION",
      "message": "No vector index was used for the base table `my_project:my_dataset.my_table` because use_brute_force option has been specified."
    }
  ],
  "indexUsageMode": "UNUSED"
}

색인 관리 옵션

색인을 만들고 BigQuery가 이를 유지보수하도록 할 때는 다음 두 가지 옵션이 있습니다.

  • 기본 공유 슬롯 풀 사용: 색인을 생성할 데이터가 조직별 한도보다 낮으면 색인 관리를 위한 공유 슬롯 풀을 무료로 사용할 수 있습니다.
  • 자체 예약 사용: 큰 프로덕션 워크로드에서 보다 예측 가능하고 일관적으로 색인을 생성하기 위해서는 색인 관리를 위해 자체 예약을 사용할 수 있습니다.

공유 슬롯 사용

색인 생성에 전용 예약을 사용하도록 프로젝트를 구성하지 않은 경우 색인 관리는 다음과 같은 제약조건에 따라 무료 공유 슬롯 풀에서 처리됩니다.

데이터를 테이블에 추가하여 색인이 생성된 테이블의 총 크기가 조직의 한도를 초과할 경우 BigQuery가 색인이 생성된 모든 테이블의 색인 관리를 일시중지합니다. 이 경우 INFORMATION_SCHEMA.VECTOR_INDEXESindex_status 필드에 PENDING DISABLEMENT가 표시되고 색인이 삭제 큐에 추가됩니다. 사용 중지 대기 중인 색인은 쿼리에 계속 사용되며 색인 스토리지 요금이 부과됩니다. 색인이 삭제되면 index_status 필드에 색인이 TEMPORARILY DISABLED로 표시됩니다. 이 상태에서는 쿼리에 색인이 사용되지 않고 색인 스토리지 요금이 청구되지 않습니다. 여기에서 IndexUnusedReason 코드BASE_TABLE_TOO_LARGE입니다.

테이블에서 데이터를 삭제하고 색인이 생성된 테이블의 총 크기가 조직별 한도 미만이 되면 색인이 생성된 모든 테이블의 색인 관리가 다시 시작됩니다. INFORMATION_SCHEMA.VECTOR_INDEXES 뷰의 index_status 필드는 ACTIVE이고 쿼리에서 색인을 사용할 수 있으며 색인 스토리지에 대한 요금이 부과됩니다.

BigQuery는 공유 풀의 사용 가능한 용량 또는 표시된 색인 생성의 처리량을 보장하지 않습니다. 프로덕션 애플리케이션의 경우 색인 처리를 위해 전용 슬롯을 사용할 수 있습니다.

자체 예약 사용

기본 공유 슬롯 풀을 사용하는 대신 자체 예약을 지정하여 테이블의 색인을 지정할 수 있습니다. 자체 예약을 사용하면 생성, 새로고침, 백그라운드 최적화와 같은 색인 관리 작업의 예측 가능한 일관된 성능을 보장할 수 있습니다.

  • 예약에서 색인 생성 작업을 실행할 때는 테이블 크기 한도가 없습니다.
  • 자체 예약을 사용하면 색인을 유연하게 관리할 수 있습니다. 매우 큰 색인을 만들거나 색인 생성된 테이블에 주요 업데이트를 수행해야 하는 경우 일시적으로 할당에 슬롯을 더 추가할 수 있습니다.

지정된 예약이 있는 프로젝트에서 테이블의 색인을 생성하려면 테이블이 위치한 리전에서 예약을 만듭니다. 그런 다음 job_typeBACKGROUND로 설정하여 예약에 프로젝트를 할당합니다.

SQL

CREATE ASSIGNMENT DDL 문을 사용합니다.

  1. Google Cloud 콘솔에서 BigQuery 페이지로 이동합니다.

    BigQuery로 이동

  2. 쿼리 편집기에서 다음 문을 입력합니다.

    CREATE ASSIGNMENT
      `ADMIN_PROJECT_ID.region-LOCATION.RESERVATION_NAME.ASSIGNMENT_ID`
    OPTIONS (
      assignee = 'projects/PROJECT_ID',
      job_type = 'BACKGROUND');
    

    다음을 바꿉니다.

    • ADMIN_PROJECT_ID: 예약 리소스를 소유하는 관리 프로젝트의 프로젝트 ID입니다.
    • LOCATION: 예약 위치입니다.
    • RESERVATION_NAME: 예약 이름입니다.
    • ASSIGNMENT_ID: 할당 ID입니다.

      ID는 프로젝트 및 위치에 고유해야 하고, 소문자 또는 숫자로 시작하고 끝나야 하고, 소문자, 숫자, 대시만 포함해야 합니다.

    • PROJECT_ID: 색인을 생성할 테이블이 포함된 프로젝트의 ID입니다. 이 프로젝트가 예약에 할당됩니다.

  3. 실행을 클릭합니다.

쿼리를 실행하는 방법에 대한 자세한 내용은 대화형 쿼리 실행을 참조하세요.

bq

bq mk 명령어를 사용합니다.

bq mk \
    --project_id=ADMIN_PROJECT_ID \
    --location=LOCATION \
    --reservation_assignment \
    --reservation_id=RESERVATION_NAME \
    --assignee_id=PROJECT_ID \
    --job_type=BACKGROUND \
    --assignee_type=PROJECT

다음을 바꿉니다.

  • ADMIN_PROJECT_ID: 예약 리소스를 소유하는 관리 프로젝트의 프로젝트 ID입니다.
  • LOCATION: 예약 위치입니다.
  • RESERVATION_NAME: 예약 이름입니다.
  • PROJECT_ID: 이 예약에 할당할 프로젝트의 ID입니다.

색인 생성 작업 보기

단일 테이블에서 색인을 만들거나 업데이트할 때마다 새로운 색인 생성 작업이 생성됩니다. 작업에 대한 정보를 보려면 INFORMATION_SCHEMA.JOBS*를 쿼리합니다. 쿼리의 WHERE 절에서 job_type IS NULL AND SEARCH(job_id, '`search_index`')를 설정하여 색인 생성 작업을 필터링할 수 있습니다. 다음 예시는 my_project 프로젝트에 있는 최근 5개의 색인 생성 작업을 보여줍니다.

SELECT *
FROM
 region-us.INFORMATION_SCHEMA.JOBS
WHERE
  project_id  = 'my_project'
  AND job_type IS NULL
  AND SEARCH(job_id, '`search_index`')
ORDER BY
 creation_time DESC
LIMIT 5;

예약 크기 선택

예약에 적합한 슬롯 수를 선택하려면 색인 관리 작업이 실행되는 시기, 사용되는 슬롯 수, 시간 경과에 따른 사용량을 고려해야 합니다. BigQuery는 다음 상황에서 색인 관리 작업을 트리거합니다.

  • 테이블에 색인을 만듭니다.
  • 색인 생성된 테이블에서 데이터가 수정됩니다.
  • 테이블의 스키마가 변경되어 색인이 생성되는 열에 영향을 미칩니다.
  • 색인 데이터 및 메타데이터가 주기적으로 최적화되거나 업데이트됩니다.

테이블에서 색인 관리 작업에 필요한 슬롯 수는 다음 요소에 따라 달라집니다.

  • 테이블 크기
  • 테이블에 대한 데이터 수집 비율
  • 테이블에 적용되는 DML 문의 비율
  • 색인 빌드 및 유지보수에 허용되는 지연 시간
  • 중복 항목 수와 같이 일반적으로 데이터 속성에 따라 결정되는 색인의 복잡성
사용량 및 진행 상태 모니터링

색인 관리 작업을 효율적으로 실행하기 위해 필요한 슬롯 수를 평가하기 위해서는 슬롯 사용률을 모니터링하고 그에 따라 예약 크기를 조정하는 것이 가장 좋습니다. 다음 쿼리는 색인 관리 작업을 위한 일일 슬롯 사용량을 보여줍니다. 이전 30일만 us-west1 리전에 포함됩니다.

SELECT
  TIMESTAMP_TRUNC(job.creation_time, DAY) AS usage_date,
  -- Aggregate total_slots_ms used for index-management jobs in a day and divide
  -- by the number of milliseconds in a day. This value is most accurate for
  -- days with consistent slot usage.
  SAFE_DIVIDE(SUM(job.total_slot_ms), (1000 * 60 * 60 * 24)) AS average_daily_slot_usage
FROM
  `region-us-west1`.INFORMATION_SCHEMA.JOBS job
WHERE
  project_id = 'my_project'
  AND job_type IS NULL
  AND SEARCH(job_id, '`search_index`')
GROUP BY
  usage_date
ORDER BY
  usage_date DESC
limit 30;

색인 관리 작업을 실행하는 데 슬롯이 부족하면 색인이 테이블과 동기화되지 않고 색인 생성 작업이 실패할 수 있습니다. 이 경우 BigQuery에서 색인을 처음부터 다시 빌드합니다. 색인이 동기화되지 않도록 방지하려면 데이터 수집 및 최적화로부터 색인 업데이트를 지원하기에 슬롯이 충분한지 확인해야 합니다. 슬롯 사용량 모니터링에 대한 자세한 내용은 관리 리소스 차트를 참조하세요.

벡터 색인 삭제

벡터 색인이 더 이상 필요하지 않거나 테이블에서 색인을 생성할 열을 변경하려면 DROP VECTOR INDEX DDL 문을 사용하여 해당 테이블에 있는 색인을 삭제하면 됩니다.

예를 들면 다음과 같습니다.

DROP VECTOR INDEX my_index ON my_dataset.indexed_table;

색인이 생성된 테이블을 삭제하면 색인이 자동으로 삭제됩니다.

다음 단계