벡터 임베딩으로 검색 및 필터링

이 페이지에서는 벡터 임베딩을 쿼리할 수 있는 다양한 방법을 설명합니다. ANN 및 KNN 유사성 검색 개요는 벡터 검색을 참고하세요.

근사 최근접 이웃(ANN) 검색

ANN 검색을 실행하려면 SELECTORDER BY 절에서 approx_distance 함수를 사용합니다. ANN 검색에서는 LIMIT 절을 사용해야 합니다. approx_distanceSELECT 목록에 넣어 거리 값을 가져올 수도 있습니다.

ANN 쿼리에는 다음 구문을 사용합니다.

# Ordering by distance
SELECT title
FROM books
ORDER BY approx_distance(embedding, string_to_vector('[1,2,3]'), 'distance_measure=l2_squared')
LIMIT 4;

# Selecting the distance value
SELECT
  approx_distance(
    embedding_name,
    string_to_vector('[1,2,3]'),
    'distance_measure=cosine,num_leaves_to_search=3')
    dist
FROM table
ORDER BY dist
LIMIT limit_value;

approx_distance 함수는 다음 옵션을 사용합니다.

  • embedding: 기본 테이블의 벡터 임베딩 열 이름을 사용합니다.
  • string_to_vector 또는 vector_to_string: 벡터를 문자열로, 문자열을 벡터로 변환하여 벡터를 인간이 읽을 수 있는 형식으로 만듭니다.
  • distance_measure: 벡터 유사성 검색에 사용할 거리 측정값을 지정합니다. 이 값은 색인을 만들 때 distance_measure 매개변수에 설정한 값과 일치해야 합니다. 이 매개변수는 필수항목입니다. 이 매개변수에 사용할 수 있는 값은 다음과 같습니다.
    • COSINE
    • L2_SQUARED
    • DOT_PRODUCT
  • num_leaves_to_search: 선택사항입니다. ANN 벡터 유사성 검색을 위해 프로브할 리프 수를 지정합니다. 리프 수를 지정하지 않으면 Cloud SQL에서 테이블 크기, 벡터 색인의 리프 수, 기타 요소를 기반으로 생성된 값을 사용합니다. 이 값은 information_schema.innodb_vector_indexes에서 확인할 수 있습니다. 특정 워크로드의 검색 품질과 성능 간의 최적의 균형을 달성하려면 num_leaves_to_search를 미세 조정하는 것이 좋습니다. 늘리면 성능에 영향을 미치지만 재현율이 향상됩니다.

다음 예시에서는 approx_distance를 사용하여 l2_squared 거리 측정값으로 Top-K 최근접 행을 찾고 거리순으로 결과를 정렬하는 방법을 보여줍니다.

# Ordering by distance
SELECT title
FROM books
ORDER BY approx_distance(embedding, string_to_vector('[1,2,3]'),
                         'distance_measure=l2_squared')
LIMIT 4;

# Selecting the distance value
SELECT
    approx_distance
        (embedding, string_to_vector('[1,2,3]'),
         'distance_measure=l2_squared') dist
FROM table
ORDER BY dist
LIMIT 4;

approx_distance 쿼리 결과 필터링

approx_distance 함수를 벡터가 아닌 서술어로 쿼리 결과를 필터링하는 WHERE 조건과 함께 사용하여 사후 필터링을 실행할 수 있습니다. approx_distance 함수가 필터를 적용하기 전에 평가되므로 반환되는 결과 수는 비결정적입니다.

예를 들면 다음 쿼리의 경우 다음과 같습니다.

SELECT id FROM products WHERE price < 100
ORDER BY approx_distance(embedding, @query_vector,'distance_measure=cosine')
LIMIT 11;

approx_distance 함수는 가격과 관계없이 쿼리 벡터에 가장 가까운 11개의 최근접 이웃을 반환합니다. 사후 필터링에서 가격이 100보다 낮은 제품이 선택됩니다. 최근접 이웃의 가격이 모두 100 미만일 수 있으므로 쿼리에 대한 결과가 11개입니다. 또는 최근접 이웃 중 가격이 100보다 낮은 항목이 없으면 반환되는 행이 0개입니다.

WHERE 조건의 필터가 매우 선택적일 것으로 예상되는 경우 정확한 검색 (KNN)이 충분한 수의 행을 반환하는 데 도움이 되는 옵션 중 하나입니다.

반복 필터링을 사용하여 더 많은 ANN 검색 색인을 스캔할 수도 있습니다.

반복 필터링을 사용하여 ANN 검색 결과 늘리기

ANN 검색 쿼리의 WHERE 절에 있는 선택적 필터가 LIMIT 절에 지정된 결과 수보다 적은 결과를 생성하는 경우 반복 필터링을 사용할 수 있습니다.

예를 들어 다음 쿼리에서 반복 필터링을 사용 설정하면 쿼리는 필터링된 첫 번째 결과 집합을 제외한 벡터 색인을 더 많이 스캔합니다.

EXPLAIN FORMAT=TREE
SELECT * FROM t1 WHERE next_id BETWEEN 15 AND 100
ORDER BY approx_distance(embedding, string_to_vector('[1,2,3]'), 'distance_measure=l2_squared')
LIMIT 10;

EXPLAIN
-> Limit: 10 row(s)  (rows=10)
   -> Vector index loop with iterative filtering
      -> Vector index scan on t1
      -> Filter: (t1.next_id between 15 and 100)
         -> Single-row index lookup on t1 using PRIMARY (id=t1.id)

구성된 최대값 (cloudsql_vector_iterative_filtering_max_neighbors)에 도달할 때까지 검색 벡터 색인에서 이웃을 반복적으로 가져옵니다. 필터와 일치하는 항목은 LIMIT에 포함되고 추가 벡터 색인 검색에서 삭제됩니다.

반복 필터링 사용 설정

기본적으로 반복 필터링은 모든 세션과 Cloud SQL 인스턴스에 대해 사용 중지되어 있습니다.

기존 세션에 대해 반복 필터링을 사용 설정하려면 다음 SQL 문을 사용하세요.

SET SESSION cloudsql_vector_iterative_filtering=on;

인스턴스에서 플래그를 설정하여 인스턴스에 연결하는 모든 클라이언트 세션에 대해 전역적으로 반복 필터링을 사용 설정할 수도 있습니다. 인스턴스에 플래그를 설정하려면 데이터베이스 플래그 설정을 참고하세요.

세션 또는 전역 수준에서 시스템 변수를 설정하는 방법에 대한 자세한 내용은 MySQL 문서의 시스템 변수 사용을 참고하세요.

반복 필터링 조정

반복 필터링이 사용 설정된 ANN 검색 쿼리에 대해 반환되는 최근접 이웃 수를 제어하려면 cloudsql_vector_iterative_filtering_max_neighbors 세션 또는 전역 시스템 변수를 사용하면 됩니다. 이 구성을 사용하여 요청되는 최근접 이웃의 수를 늘릴 수 있습니다. 하지만 메모리에 너무 많은 결과가 저장되지 않도록 이 변수의 최댓값은 1000입니다.

세션에 이 변수를 설정하려면 다음 SQL 문을 사용하세요.

SET cloudsql_vector_iterative_filtering_max_neighbors=600;

기본값은 500이고 최소 수는 10입니다.

제한사항

반복 필터링 사용 시 제한사항은 다음과 같습니다.

  • 보장되지 않음: 반복 필터링을 사용하면 Cloud SQL에서 LIMIT 절에 지정된 결과 수를 찾으려고 시도하지만 해당 수가 발견된다고 보장하지는 않습니다. LIMIT이 충족되기 전에 최대 이웃 수 (cloudsql_vector_iterative_filtering_max_neighbors)에 도달하거나 표에서 필터와 일치하는 행이 충분하지 않은 경우에 발생할 수 있습니다.

  • 복잡한 쿼리: 반복 필터링은 필터 조건자가 기본 테이블의 액세스 경로로 푸시되는 경우에만 작동합니다. HAVING 절을 사용하는 테이블과 같은 임시 테이블 위의 필터에는 지원되지 않습니다. 하위 쿼리에서는 하위 쿼리 자체 내의 기본 테이블에 대한 필터만 반복 필터링에 고려됩니다.

ANN 검색의 대체 상태 확인

ANN 검색이 KNN 검색으로 대체되는 경우가 있습니다. 예를 들면 다음과 같습니다.

  • 기본 테이블에 벡터 색인이 없습니다.
  • 기본 테이블에 벡터 색인이 있지만 approx_distance 검색 옵션의 distance_measure 매개변수와 다른 거리 측정을 사용합니다.
  • 벡터 색인이 손상되었거나 현재 트랜잭션에 표시되지 않습니다.
  • 지정된 LIMIT이 10,000보다 큽니다.
  • 지정된 LIMIT이 없는 경우
  • 현재 쿼리에 동일한 기본 테이블에 대한 approx_distance 호출이 두 개 이상 포함되어 있습니다.
  • 옵티마이저의 계산에 따르면 KNN을 사용하는 것이 더 효율적입니다.

이러한 모든 경우 클라이언트에 정확한 검색이 실행되었음을 나타내는 주의와 그 이유가 전송됩니다.

mysql 클라이언트에서 다음 명령어를 사용하여 대체 상태를 확인합니다.

SHOW global status LIKE '%cloudsql_vector_knn_fallback%';

ANN을 사용하고 싶은데 KNN으로 대체되는 경우 쿼리가 더 느리게 실행될 수 있습니다. 폴백되는 이유를 찾아 ANN이 대신 사용되도록 변경할지 평가해야 합니다.

예시: 벡터 색인 만들기 및 ANN 쿼리 실행

다음 예시 연습에서는 Cloud SQL에서 벡터 색인을 만들고 ANN 쿼리를 실행하는 단계를 보여줍니다.

  1. 벡터 임베딩을 생성합니다. 벡터 임베딩을 수동으로 만들거나 원하는 텍스트 임베딩 API를 사용할 수 있습니다. Vertex AI를 사용하는 예시는 행 데이터를 기반으로 벡터 임베딩 생성을 참조하세요.
  2. Cloud SQL에서 3개 차원이 있는 벡터 임베딩 열을 포함하는 테이블을 만듭니다.

    CREATE TABLE books(
    id INTEGER PRIMARY KEY AUTO_INCREMENT, title VARCHAR(60), embedding VECTOR(3) USING VARBINARY);
    
  3. 열에 벡터 임베딩을 삽입합니다.

    INSERT INTO books VALUES ((1, 'book title', string_to_vector('[1,2,3]')));
    
  4. 변경사항을 커밋합니다.

    commit;
    
  5. L2_squared 함수를 사용하여 거리를 측정하는 벡터 색인을 만듭니다.

    CREATE
      VECTOR INDEX vectorIndex
    ON dbname.books(embeddings)
    USING SCANN QUANTIZER = SQ8 DISTANCE_MEASURE = l2_squared;
    
  6. 다음 문법을 사용하여 검색 결과 4개의 LIMIT을 사용하여 ANN 검색을 실행합니다.

    SELECT title
    FROM books
    ORDER BY approx_distance(embedding, string_to_vector('[1,2,3]'), 'distance_measure=l2_squared')
    LIMIT 4;
    
    SELECT approx_distance(embedding, string_to_vector('[1,2,3]'), 'distance_measure=cosine') dist
    FROM books
    ORDER BY dist
    LIMIT 4;
    

K-최근접 이웃(KNN) 검색

K-최근접 이웃 검색을 실행하려면 SELECT 문에서 거리 측정 옵션과 벡터 변환 함수(string_to_vector 또는 vector_to_string)와 함께 vector_distance 함수를 사용합니다. 다음 구문을 사용합니다.

SELECT vector_distance(string_to_vector('[1,2,3]'),
                      string_to_vector('[1,2,3]'),
                      'Distance_Measure=dot_product');

[1,2,3] 값을 데이터의 임베딩 값으로 바꿉니다.

다음 예시에서는 이 쿼리를 cosine_distance 함수 및 string_to_vector 벡터 변환 함수와 함께 사용하는 방법을 보여줍니다.

SELECT id,cosine_distance(embedding, string_to_vector('[1,2,3]')) dist
FROM books
ORDER BY distance
LIMIT 10;

KNN 쿼리에서 코사인 거리 가져오기

Cloud SQL cosine_distance 함수로 코사인을 사용하여 거리를 계산합니다.

SELECT cosine_distance(embedding, string_to_vector('[3,1,2]')) AS distance FROM books WHERE id = 10;

KNN 쿼리에서 내적 거리 가져오기

Cloud SQL dot_product 함수로 내적을 사용하여 거리를 계산합니다.

SELECT dot_product(embedding, string_to_vector('[3,1,2]')) AS distance FROM books WHERE id = 10;

KNN 쿼리에서 L2 제곱 거리 가져오기

Cloud SQL l2_squared_distance 함수로 L2 제곱을 사용하여 거리를 계산합니다.

SELECT
  l2_squared_distance(embedding, string_to_vector('[3,1,2]'))
    AS distance
FROM books
WHERE id = 10;

다음 단계