Начало работы с векторными внедрениями в Cloud SQL для MySQL

Начало работы с векторными внедрениями в Cloud SQL для MySQL

О практической работе

subjectПоследнее обновление: апр. 22, 2025
account_circleАвторы: Gleb Otochkin

1. Введение

В этой лабораторной работе вы узнаете, как использовать Cloud SQL для интеграции MySQL с Vertex AI путем объединения векторного поиска с внедрениями Vertex AI.

30b7c4dcdd8bb68f.png

Предварительные условия

  • Базовое понимание Google Cloud, консоли.
  • Базовые навыки работы с интерфейсом командной строки и Cloud Shell.

Что вы узнаете

  • Как развернуть экземпляр Cloud SQL для MySQL
  • Как создать базу данных и включить интеграцию Cloud SQL AI
  • Как загрузить данные в базу данных
  • Как использовать модель внедрения Vertex AI в Cloud SQL
  • Как обогатить результат с помощью генеративной модели Vertex AI
  • Как повысить производительность с помощью векторного индекса

Что вам понадобится

  • Учетная запись Google Cloud и проект Google Cloud
  • Веб-браузер, например Chrome, с поддержкой консоли Google Cloud и Cloud Shell.

2. Настройка и требования

Самостоятельная настройка среды

  1. Войдите в Google Cloud Console и создайте новый проект или повторно используйте существующий. Если у вас еще нет учетной записи Gmail или Google Workspace, вам необходимо ее создать .

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • Имя проекта — это отображаемое имя для участников этого проекта. Это строка символов, не используемая API Google. Вы всегда можете обновить его.
  • Идентификатор проекта уникален для всех проектов Google Cloud и является неизменяемым (невозможно изменить после его установки). Cloud Console автоматически генерирует уникальную строку; обычно тебя не волнует, что это такое. В большинстве лабораторий кода вам потребуется указать идентификатор проекта (обычно идентифицируемый как PROJECT_ID ). Если вам не нравится сгенерированный идентификатор, вы можете создать другой случайный идентификатор. Альтернативно, вы можете попробовать свой собственный и посмотреть, доступен ли он. Его нельзя изменить после этого шага и он сохраняется на протяжении всего проекта.
  • К вашему сведению, есть третье значение — номер проекта , которое используют некоторые API. Подробнее обо всех трех этих значениях читайте в документации .
  1. Затем вам необходимо включить выставление счетов в Cloud Console, чтобы использовать облачные ресурсы/API. Прохождение этой кодовой лаборатории не будет стоить много, если вообще что-то стоить. Чтобы отключить ресурсы и избежать выставления счетов за пределами этого руководства, вы можете удалить созданные вами ресурсы или удалить проект. Новые пользователи Google Cloud имеют право на участие в программе бесплатной пробной версии стоимостью 300 долларов США .

Запустить Cloud Shell

Хотя Google Cloud можно управлять удаленно с вашего ноутбука, в этой лаборатории вы будете использовать Google Cloud Shell , среду командной строки, работающую в облаке.

В Google Cloud Console щелкните значок Cloud Shell на верхней правой панели инструментов:

55efc1aaa7a4d3ad.png

Подготовка и подключение к среде займет всего несколько минут. Когда все будет готово, вы должны увидеть что-то вроде этого:

7ffe5cbb04455448.png

Эта виртуальная машина оснащена всеми необходимыми инструментами разработки. Он предлагает постоянный домашний каталог объемом 5 ГБ и работает в Google Cloud, что значительно повышает производительность сети и аутентификацию. Всю работу в этой лаборатории кода можно выполнять в браузере. Вам не нужно ничего устанавливать.

3. Прежде чем начать

Включить API

В Cloud Shell убедитесь, что идентификатор вашего проекта настроен:

gcloud config set project [YOUR-PROJECT-ID]

Установите переменную среды PROJECT_ID:

PROJECT_ID=$(gcloud config get-value project)

Включите все необходимые службы:

gcloud services enable sqladmin.googleapis.com \
                       compute
.googleapis.com \
                       cloudresourcemanager
.googleapis.com \
                       servicenetworking
.googleapis.com \
                       aiplatform
.googleapis.com

Ожидаемый результат

student@cloudshell:~ (test-project-001-402417)$ gcloud config set project test-project-001-402417
Updated property [core/project].
student@cloudshell:~ (test-project-001-402417)$ PROJECT_ID=$(gcloud config get-value project)
Your active configuration is: [cloudshell-14650]
student@cloudshell:~ (test-project-001-402417)$ 
student@cloudshell:~ (test-project-001-402417)$ gcloud services enable sqladmin.googleapis.com \
                       compute.googleapis.com \
                       cloudresourcemanager.googleapis.com \
                       servicenetworking.googleapis.com \
                       aiplatform.googleapis.com
Operation "operations/acat.p2-4470404856-1f44ebd8-894e-4356-bea7-b84165a57442" finished successfully.

4. Создайте экземпляр Cloud SQL

Создайте экземпляр Cloud SQL с интеграцией базы данных с Vertex AI.

Создать пароль базы данных

Определите пароль для пользователя базы данных по умолчанию. Вы можете определить свой собственный пароль или использовать случайную функцию для его генерации:

export CLOUDSQL_PASSWORD=`openssl rand -hex 12`

Обратите внимание на сгенерированное значение пароля:

echo $CLOUDSQL_PASSWORD

Создать экземпляр Cloud SQL для MySQL

Флаг cloudsql_vector можно включить при создании экземпляра. Поддержка векторов в настоящее время доступна для MySQL 8.0 R20241208.01_00 или новее.

В сеансе Cloud Shell выполните:

gcloud sql instances create my-cloudsql-instance \
--database-version=MYSQL_8_4 \
--tier=db-custom-2-8192 \
--region=us-central1 \
--enable-google-ml-integration \
--edition=ENTERPRISE \
--root-password=$CLOUDSQL_PASSWORD

Мы можем проверить наше соединение, выполнив его из Cloud Shell.

gcloud sql connect my-cloudsql-instance --user=root

Запустите команду и введите свой пароль в командную строку, когда она будет готова к подключению.

Ожидаемый результат:

$gcloud sql connect my-cloudsql-instance --user=root
Allowlisting your IP for incoming connection for 5 minutes...done.                                                                                                                           
Connecting to database with SQL user [root].Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 71
Server version: 8.4.4-google (Google)

Copyright (c) 2000, 2025, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

Включить интеграцию Vertex AI

Предоставьте необходимые привилегии внутренней учетной записи облачной службы sql, чтобы иметь возможность использовать интеграцию Vertex AI.

Найдите адрес электронной почты внутренней учетной записи службы Cloud SQL и экспортируйте его как переменную.

SERVICE_ACCOUNT_EMAIL=$(gcloud sql instances describe my-cloudsql-instance --format="value(serviceAccountEmailAddress)")
echo $SERVICE_ACCOUNT_EMAIL

Предоставьте доступ к Vertex AI сервисному аккаунту Cloud SQL:

gcloud projects add-iam-policy-binding $PROJECT_ID \
 
--member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" \
 
--role="roles/aiplatform.user"

Подробнее о создании и настройке экземпляра читайте в документации Cloud SQL здесь .

5. Подготовить базу данных

Теперь нам нужно создать базу данных и включить поддержку векторов.

Создать базу данных

Создайте базу данных с именем faststart_db . Для этого у нас есть различные варианты, такие как клиенты базы данных командной строки, такие как mysql для mySQL, SDK или Cloud SQL Studio. Для создания базы данных мы будем использовать SDK (gcloud).

В Cloud Shell выполните команду для создания базы данных.

gcloud sql databases create quickstart_db --instance=my-cloudsql-instance

6. Загрузить данные

Теперь нам нужно создать объекты в базе данных и загрузить данные. Мы собираемся использовать вымышленные данные Cymbal Store. Данные доступны в формате SQL (для схемы) и CSV (для данных).

Cloud Shell будет нашей основной средой для подключения к базе данных, создания всех объектов и загрузки данных.

Сначала нам нужно добавить общедоступный IP-адрес Cloud Shell в список авторизованных сетей для нашего экземпляра Cloud SQL. В облачной оболочке выполните:

gcloud sql instances patch my-cloudsql-instance --authorized-networks=$(curl ifconfig.me)

Если ваш сеанс был потерян, сброшен или вы работаете с другим инструментом, экспортируйте переменную CLOUDSQL_PASSWORD еще раз:

export CLOUDSQL_PASSWORD=...your password defined for the instance...

Теперь мы можем создать все необходимые объекты в нашей базе данных. Для этого мы собираемся использовать утилиту MySQL MySQL в сочетании с утилитой Curl , которая получает данные из общедоступного источника.

В облачной оболочке выполните:

export INSTANCE_IP=$(gcloud sql instances describe my-cloudsql-instance --format="value(ipAddresses.ipAddress)")
curl -LJ https://raw.githubusercontent.com/GoogleCloudPlatform/devrel-demos/main/infrastructure/cymbal-store-embeddings/cymbal_mysql_schema.sql | mysql --host=$INSTANCE_IP --user=root --password=$CLOUDSQL_PASSWORD quickstart_db

Что именно мы сделали в предыдущей команде? Мы подключились к нашей базе данных и выполнили загруженный код SQL, который создал таблицы, индексы и последовательности.

Следующим шагом будет загрузка данных cymbal_products. Мы используем те же утилиты Curl и MySQL .

curl -LJ https://raw.githubusercontent.com/GoogleCloudPlatform/devrel-demos/main/infrastructure/cymbal-store-embeddings/cymbal_products.csv | mysql --enable-local-infile --host=$INSTANCE_IP --user=root --password=$CLOUDSQL_PASSWORD quickstart_db -e "LOAD DATA LOCAL INFILE '/dev/stdin'  INTO TABLE cymbal_products FIELDS TERMINATED BY ','  OPTIONALLY ENCLOSED BY '\"'  LINES TERMINATED BY '\n'  IGNORE 1 LINES;"

Затем мы продолжаем работу с cymbal_stores.

curl -LJ https://raw.githubusercontent.com/GoogleCloudPlatform/devrel-demos/main/infrastructure/cymbal-store-embeddings/cymbal_stores.csv | mysql --enable-local-infile --host=$INSTANCE_IP --user=root --password=$CLOUDSQL_PASSWORD quickstart_db -e "LOAD DATA LOCAL INFILE '/dev/stdin'  INTO TABLE cymbal_stores FIELDS TERMINATED BY ','  OPTIONALLY ENCLOSED BY '\"'  LINES TERMINATED BY '\n'  IGNORE 1 LINES;"

И в комплекте с cymbal_inventory, в котором указано количество каждого товара в каждом магазине.

curl -LJ https://raw.githubusercontent.com/GoogleCloudPlatform/devrel-demos/main/infrastructure/cymbal-store-embeddings/cymbal_inventory.csv | mysql --enable-local-infile --host=$INSTANCE_IP --user=root --password=$CLOUDSQL_PASSWORD quickstart_db -e "LOAD DATA LOCAL INFILE '/dev/stdin'  INTO TABLE cymbal_inventory FIELDS TERMINATED BY ','  OPTIONALLY ENCLOSED BY '\"'  LINES TERMINATED BY '\n'  IGNORE 1 LINES;"

Если у вас есть собственные образцы данных и файлы CSV, совместимые с инструментом импорта Cloud SQL, доступным из консоли Cloud, вы можете использовать его вместо представленного подхода.

7. Создание вложений

Следующим шагом будет создание вложений для описаний наших продуктов с использованием модели textembedding-005 от Google Vertex AI и сохранение их в новом столбце таблицы cymbal_products.

Чтобы хранить векторные данные, нам необходимо включить векторную функциональность в нашем экземпляре Cloud SQL. Выполните в Cloud Shell:

gcloud sql instances patch my-cloudsql-instance \
--database-flags=cloudsql_vector=on

Подключитесь к базе данных:

mysql --host=$INSTANCE_IP --user=root --password=$CLOUDSQL_PASSWORD quickstart_db

И создайте встраивание виртуального столбца в нашу таблицу cymbal_products, используя функцию встраивания.

ALTER TABLE cymbal_products ADD COLUMN embedding vector(768) using varbinary;
UPDATE cymbal_products SET embedding = mysql.ml_embedding('text-embedding-005', product_description);

Создание векторных векторных представлений для 2000 строк обычно занимает менее 5 минут, но иногда может занять немного больше времени и часто завершается намного быстрее.

8. Запустите поиск по сходству

Теперь мы можем запустить поиск, используя поиск по сходству на основе векторных значений, рассчитанных для описаний, и векторного значения, которое мы генерируем для нашего запроса с использованием той же модели внедрения.

SQL-запрос можно выполнить из того же интерфейса командной строки или, в качестве альтернативы, из Cloud SQL Studio. Любой многострочный и сложный запрос лучше обрабатывать в Cloud SQL Studio.

Создать пользователя

Нам нужен новый пользователь, который сможет использовать Cloud SQL Studio. Мы собираемся создать пользователя-ученика встроенного типа с тем же паролем, который мы использовали для пользователя root.

В Cloud Shell выполните:

gcloud sql users create student  --instance=my-cloudsql-instance --password=$CLOUDSQL_PASSWORD --host=%

Запустите Cloud SQL Studio.

В консоли щелкните экземпляр Cloud SQL, который мы создали ранее.

667b658dbf98eb0b.png

Когда он открыт на правой панели, мы видим Cloud SQL Studio. Нажмите на него.

a879e8ac914a8ce9.png

Откроется диалоговое окно, в котором вы укажите имя базы данных и свои учетные данные:

  • База данных: faststart_db
  • Пользователь: студент
  • Пароль: записанный вами пароль для пользователя.

И нажмите кнопку «АУТЕНТИФИКАЦИЯ».

36e6036847333d18.png

Откроется следующее окно, в котором вы щелкнете вкладку «Редактор» справа, чтобы открыть редактор SQL.

d803b7b6a798094f.png

Теперь мы готовы выполнить наши запросы.

Запустить запрос

Запустите запрос, чтобы получить список доступных продуктов, наиболее соответствующих запросу клиента. Запрос, который мы собираемся передать Vertex AI для получения значения вектора, звучит так: «Какие фруктовые деревья здесь хорошо растут?»

Вот запрос, который вы можете выполнить, чтобы выбрать первые 5 элементов, наиболее подходящих для нашего запроса, используя функцию cosine_distance:

SELECT mysql.ML_EMBEDDING('text-embedding-005','What kind of fruit trees grow well here?') into @query_vector;
SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        cosine_distance(cp.embedding ,@query_vector) as distance
FROM
        cymbal_products cp
JOIN cymbal_inventory ci on
        ci.uniq_id=cp.uniq_id
JOIN cymbal_stores cs on
        cs.store_id=ci.store_id
        AND ci.inventory>0
        AND cs.store_id = 1583
ORDER BY
        distance ASC
LIMIT 5;

Скопируйте и вставьте запрос в редактор Cloud SQL Studio и нажмите кнопку «Выполнить» или вставьте его в сеанс командной строки, подключающийся к базе данных faststart_db.

dffc70835901cf03.png

А вот список продуктов, выбранных по запросу.

+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
| product_name    | description                                                                      | sale_price | zip_code | distance            |
+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
| Malus Domestica | Malus Domestica, the classic apple tree, brings beauty and delicious fruit to yo |     100.00 |    93230 | 0.37740096545831603 |
| Cerasus         | Cerasus: A beautiful cherry tree that brings delicious fruit and vibrant color t |      75.00 |    93230 |   0.405704177142419 |
| Persica         | Persica: Enjoy homegrown, delicious peaches with this beautiful peach tree. Reac |     150.00 |    93230 | 0.41031799106722877 |
| Meyer Lemon     | Grow your own juicy Meyer Lemons with this semi-dwarf tree, California's favorit |      34.00 |    93230 | 0.42823360959352186 |
| Acer            | Acer, the classic maple. Known for vibrant fall foliage in reds, oranges, and ye |     100.00 |    93230 | 0.42953897057301615 |
+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
5 rows in set (0.13 sec)

Выполнение запроса с функцией cosine_distance заняло 0,13 секунды.

Теперь мы запускаем тот же запрос, но используем поиск KNN с использованием функции приблизительного расстояния. Если у нас нет индекса ANN для наших вложений, он автоматически возвращается к точному скрытому поиску:

SELECT mysql.ML_EMBEDDING('text-embedding-005','What kind of fruit trees grow well here?') into @query_vector;
SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        approx_distance(cp.embedding ,@query_vector, 'distance_measure=cosine') as distance
FROM
        cymbal_products cp
JOIN cymbal_inventory ci on
        ci.uniq_id=cp.uniq_id
JOIN cymbal_stores cs on
        cs.store_id=ci.store_id
        AND ci.inventory>0
        AND cs.store_id = 1583
ORDER BY
        distance ASC
LIMIT 5;

А вот список продуктов, возвращаемых запросом.

+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
| product_name    | description                                                                      | sale_price | zip_code | distance            |
+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
| Malus Domestica | Malus Domestica, the classic apple tree, brings beauty and delicious fruit to yo |     100.00 |    93230 | 0.37740096545831603 |
| Cerasus         | Cerasus: A beautiful cherry tree that brings delicious fruit and vibrant color t |      75.00 |    93230 |   0.405704177142419 |
| Persica         | Persica: Enjoy homegrown, delicious peaches with this beautiful peach tree. Reac |     150.00 |    93230 | 0.41031799106722877 |
| Meyer Lemon     | Grow your own juicy Meyer Lemons with this semi-dwarf tree, California's favorit |      34.00 |    93230 | 0.42823360959352186 |
| Acer            | Acer, the classic maple. Known for vibrant fall foliage in reds, oranges, and ye |     100.00 |    93230 | 0.42953897057301615 |
+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
5 rows in set, 1 warning (0.12 sec)

Выполнение запроса заняло всего 0,12 секунды. Мы получили те же результаты, что и для функции cosine_distance.

9. Улучшите ответ LLM, используя полученные данные

Мы можем улучшить ответ Gen AI LLM клиентскому приложению, используя результат выполненного запроса, и подготовить значимый вывод, используя предоставленные результаты запроса как часть приглашения к модели генеративного базового языка Vertex AI.

Для этого нам нужно сгенерировать JSON с нашими результатами векторного поиска, а затем использовать этот сгенерированный JSON в качестве дополнения к подсказке для модели LLM в Vertex AI, чтобы создать значимый результат. На первом этапе мы генерируем JSON, затем тестируем его в Vertex AI Studio, а на последнем этапе включаем его в оператор SQL, который можно использовать в приложении.

Создать вывод в формате JSON

Измените запрос, чтобы он генерировал выходные данные в формате JSON и возвращал только одну строку для передачи в Vertex AI.

Вот пример запроса с использованием поиска ANN:

SELECT mysql.ML_EMBEDDING('text-embedding-005','What kind of fruit trees grow well here?') into @query_vector;
WITH trees as (
SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        cp.uniq_id as product_id
FROM
        cymbal_products cp
JOIN cymbal_inventory ci on
        ci.uniq_id=cp.uniq_id
JOIN cymbal_stores cs on
        cs.store_id=ci.store_id
        AND ci.inventory>0
        AND cs.store_id = 1583
ORDER BY
        (approx_distance(cp.embedding ,@query_vector, 'distance_measure=cosine')) ASC
LIMIT 1)
SELECT json_arrayagg(json_object('product_name',product_name,'description',description,'sale_price',sale_price,'zip_code',zip_code,'product_id',product_id)) FROM trees;

А вот ожидаемый JSON на выходе:

[{"zip_code": 93230, "product_id": "23e41a71d63d8bbc9bdfa1d118cfddc5", "sale_price": 100.00, "description": "Malus Domestica, the classic apple tree, brings beauty and delicious fruit to yo", "product_name": "Malus Domestica"}]

Запустите командную строку в Vertex AI Studio.

Мы можем использовать сгенерированный JSON, чтобы предоставить его как часть запроса на генеративную текстовую модель ИИ в Vertex AI Studio.

Откройте приглашение Vertex AI Studio в облачной консоли.

411ffb9d164ac140.png

Он может попросить вас включить дополнительные API, но вы можете игнорировать этот запрос. Для завершения нашей лаборатории нам не нужны никакие дополнительные API.

Вот подсказка, которую мы собираемся использовать:

You are a friendly advisor helping to find a product based on the customer's needs.
Based on the client request we have loaded a list of products closely related to search.
The list in JSON format with list of values like {"product_name":"name","description":"some description","sale_price":10,"zip_code": 10234, "produt_id": "02056727942aeb714dc9a2313654e1b0"}
Here is the list of products:
[place your JSON here]
The customer asked "What tree is growing the best here?"
You should give information about the product, price and some supplemental information.
Do not ask any additional questions and assume location based on the zip code provided in the list of products.

А вот как это выглядит, когда мы заменяем заполнитель JSON ответом на запрос:

You are a friendly advisor helping to find a product based on the customer's needs.
Based on the client request we have loaded a list of products closely related to search.
The list in JSON format with list of values like {"product_name":"name","description":"some description","sale_price":10,"zip_code": 10234, "produt_id": "02056727942aeb714dc9a2313654e1b0"}
Here is the list of products:
{"zip_code": 93230, "product_id": "23e41a71d63d8bbc9bdfa1d118cfddc5", "sale_price": 100.00, "description": "Malus Domestica, the classic apple tree, brings beauty and delicious fruit to yo", "product_name": "Malus Domestica"}
The customer asked "What tree is growing the best here?"
You should give information about the product, price and some supplemental information.
Do not ask any additional questions and assume location based on the zip code provided in the list of products.

И вот результат, когда мы запускаем приглашение с нашими значениями JSON и используем модель Gemini-2.0-flash:

9839af512686130d.png

Ответ, который мы получили от модели в этом примере, следует с использованием результатов семантического поиска и наиболее подходящего продукта, доступного в указанном почтовом индексе.

Запустите командную строку в PSQL

Мы также можем использовать интеграцию Cloud SQL AI с Vertex AI, чтобы получить аналогичный ответ от генеративной модели, использующей SQL непосредственно в базе данных.

Теперь мы можем использовать сгенерированные в подзапросе результаты JSON, чтобы предоставить их как часть приглашения для генеративной текстовой модели ИИ с использованием SQL.

В сеансе mysql или Cloud SQL Studio к базе данных выполните запрос.

SELECT mysql.ML_EMBEDDING('text-embedding-005','What kind of fruit trees grow well here?') into @query_vector;
WITH trees AS (
SELECT
        cp.product_name,
        cp.product_description AS description,
        cp.sale_price,
        cs.zip_code,
        cp.uniq_id AS product_id
FROM
        cymbal_products cp
JOIN cymbal_inventory ci ON
        ci.uniq_id = cp.uniq_id
JOIN cymbal_stores cs ON
        cs.store_id = ci.store_id
        AND ci.inventory>0
        AND cs.store_id = 1583
ORDER BY
         (approx_distance(cp.embedding ,@query_vector, 'distance_measure=cosine')) ASC
LIMIT 1),
prompt AS (
SELECT
       CONCAT( 'You are a friendly advisor helping to find a product based on the customer''s needs.
Based on the client request we have loaded a list of products closely related to search.
The list in JSON format with list of values like {"product_name":"name","product_description":"some description","sale_price":10}
Here is the list of products:', json_arrayagg(json_object('product_name',trees.product_name,'description',trees.description,'sale_price',trees.sale_price,'zip_code',trees.zip_code,'product_id',trees.product_id)) , 'The customer asked "What kind of fruit trees grow well here?"
You should give information about the product, price and some supplemental information') AS prompt_text
FROM
        trees),
response AS (
SELECT
       mysql.ML_PREDICT_ROW('publishers/google/models/gemini-2.0-flash-001:generateContent',
        json_object('contents',
        json_object('role',
        'user',
        'parts',
        json_array(
        json_object('text',
        prompt_text))))) AS resp
FROM
        prompt)
SELECT
JSON_EXTRACT(resp, '$.candidates[0].content.parts[0].text')
FROM
        response;

И вот пример вывода. Результат может отличаться в зависимости от версии и параметров модели:

"Okay, I see you're looking for fruit trees that grow well in your area. Based on the available product, the **Malus Domestica** (Apple Tree) is a great option to consider!\n\n* **Product:** Malus Domestica (Apple Tree)\n* **Description:** This classic apple tree grows to about 30 feet tall and provides beautiful seasonal color with green leaves in summer and fiery colors in the fall. It's known for its strength and provides good shade. Most importantly, it produces delicious apples!\n* **Price:** \\$100.00\n* **Growing Zones:** This particular apple tree is well-suited for USDA zones 4-8. Since your zip code is 93230, you are likely in USDA zone 9a or 9b. While this specific tree is rated for zones 4-8, with proper care and variety selection, apple trees can still thrive in slightly warmer climates. You may need to provide extra care during heat waves.\n\n**Recommendation:** I would recommend investigating varieties of Malus Domestica suited to slightly warmer climates or contacting a local nursery/arborist to verify if it is a good fit for your local climate conditions.\n"

Вывод предоставляется в формате уценки.

10. Создать индекс ближайшего соседа

Наш набор данных относительно невелик, и время ответа в первую очередь зависит от взаимодействия с моделями ИИ. Но когда у вас есть миллионы векторов, векторный поиск может занять значительную часть времени нашего ответа и создать высокую нагрузку на систему. Чтобы улучшить это, мы можем построить индекс поверх наших векторов.

Создать индекс ScANN

Для нашего теста мы собираемся попробовать тип индекса ScANN.

Чтобы построить индекс для нашего столбца внедрения, нам нужно определить измерение расстояния для столбца внедрения. Подробно о параметрах можно прочитать в документации .

CREATE VECTOR INDEX cymbal_products_embedding_idx ON cymbal_products(embedding) USING SCANN DISTANCE_MEASURE=COSINE;

Сравните ответ

Теперь мы можем снова запустить запрос на поиск вектора и увидеть результаты.

SELECT mysql.ML_EMBEDDING('text-embedding-005','What kind of fruit trees grow well here?') into @query_vector;
SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        approx_distance(cp.embedding ,@query_vector, 'distance_measure=cosine') as distance
FROM
        cymbal_products cp
JOIN cymbal_inventory ci on
        ci.uniq_id=cp.uniq_id
JOIN cymbal_stores cs on
        cs.store_id=ci.store_id
        AND ci.inventory>0
        AND cs.store_id = 1583
ORDER BY
        distance ASC
LIMIT 5;

Ожидаемый результат:

+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
| product_name    | description                                                                      | sale_price | zip_code | distance            |
+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
| Malus Domestica | Malus Domestica, the classic apple tree, brings beauty and delicious fruit to yo |     100.00 |    93230 | 0.37740096545831603 |
| Cerasus         | Cerasus: A beautiful cherry tree that brings delicious fruit and vibrant color t |      75.00 |    93230 |   0.405704177142419 |
| Persica         | Persica: Enjoy homegrown, delicious peaches with this beautiful peach tree. Reac |     150.00 |    93230 | 0.41031799106722877 |
| Meyer Lemon     | Grow your own juicy Meyer Lemons with this semi-dwarf tree, California's favorit |      34.00 |    93230 | 0.42823360959352186 |
| Acer            | Acer, the classic maple. Known for vibrant fall foliage in reds, oranges, and ye |     100.00 |    93230 | 0.42953897057301615 |
+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
5 rows in set (0.08 sec)

Мы видим, что время выполнения немного отличалось, но это ожидаемо для такого небольшого набора данных. Это должно быть гораздо более заметно для больших наборов данных с миллионами векторов.

И мы можем посмотреть план выполнения с помощью команды EXPLAIN:

SELECT mysql.ML_EMBEDDING('text-embedding-005','What kind of fruit trees grow well here?') into @query_vector;
EXPLAIN ANALYZE SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        approx_distance(cp.embedding ,@query_vector, 'distance_measure=cosine') as distance
FROM
        cymbal_products cp
JOIN cymbal_inventory ci on
        ci.uniq_id=cp.uniq_id
JOIN cymbal_stores cs on
        cs.store_id=ci.store_id
        AND ci.inventory>0
        AND cs.store_id = 1583
ORDER BY
        distance ASC
LIMIT 5;

План выполнения (отрывок):

...
-> Nested loop inner join  (cost=443 rows=5) (actual time=1.14..1.18 rows=5 loops=1)
                                -> Vector index scan on cp  (cost=441 rows=5) (actual time=1.1..1.1 rows=5 loops=1)
                                -> Single-row index lookup on cp using PRIMARY (uniq_id=cp.uniq_id)  (cost=0.25 rows=1) (actual time=0.0152..0.0152 rows=1 loops=5)

...

Мы видим, что он использовал сканирование векторного индекса на cp (псевдоним таблицы cymbal_products).

Вы можете поэкспериментировать со своими данными или протестировать различные поисковые запросы, чтобы увидеть, как работает семантический поиск в MySQL.

11. Очистить окружающую среду

Удалить экземпляр Cloud SQL

Уничтожьте экземпляр Cloud SQL, когда закончите лабораторную работу.

В облачной оболочке определите переменные проекта и среды, если вы были отключены и все предыдущие настройки потеряны:

export INSTANCE_NAME=my-cloudsql-instance
export PROJECT_ID=$(gcloud config get-value project)

Удалите экземпляр:

gcloud sql instances delete $INSTANCE_NAME --project=$PROJECT_ID

Ожидаемый вывод консоли:

student@cloudshell:~$ gcloud sql instances delete $INSTANCE_NAME --project=$PROJECT_ID
All of the instance data will be lost when the instance is deleted.

Do you want to continue (Y/n)?  y

Deleting Cloud SQL instance...done.                                                                                                                
Deleted [https://sandbox.googleapis.com/v1beta4/projects/test-project-001-402417/instances/my-cloudsql-instance].

12. Поздравления

Поздравляем с завершением работы над кодом.

Что мы рассмотрели

  • Как развернуть экземпляр Cloud SQL для MySQL
  • Как создать базу данных и включить интеграцию Cloud SQL AI
  • Как загрузить данные в базу данных
  • Как использовать модель внедрения Vertex AI в Cloud SQL
  • Как обогатить результат с помощью генеративной модели Vertex AI
  • Как повысить производительность с помощью векторного индекса

Попробуйте аналогичный код для AlloyDB или код для Cloud SQL для Postgres.

13. Опрос

Выход:

Как вы будете использовать этот урок?