Cloud SQL for MySQL でベクトル エンベディングを使用する

1. はじめに

この Codelab では、ベクトル検索と Vertex AI エンベディングを組み合わせて、Cloud SQL for MySQL Vertex AI 統合を使用する方法について学習します。

30b7c4dcdd8bb68f.png

前提条件

  • Google Cloud コンソールの基本的な知識
  • コマンドライン インターフェースと Cloud Shell の基本的なスキル

学習内容

  • Cloud SQL for MySQL インスタンスをデプロイする方法
  • データベースを作成し、Cloud SQL AI インテグレーションを有効にする方法
  • データベースにデータを読み込む方法
  • Cloud SQL で Vertex AI エンベディング モデルを使用する方法
  • Vertex AI 生成モデルを使用して結果を拡充する方法
  • ベクトル インデックスを使用してパフォーマンスを改善する方法

必要なもの

  • Google Cloud アカウントと Google Cloud プロジェクト
  • Google Cloud コンソールと Cloud Shell をサポートするウェブブラウザ(Chrome など)

2. 設定と要件

セルフペース型の環境設定

  1. Google Cloud Console にログインして、プロジェクトを新規作成するか、既存のプロジェクトを再利用します。Gmail アカウントも Google Workspace アカウントもまだお持ちでない場合は、アカウントを作成してください。

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • プロジェクト名は、このプロジェクトの参加者に表示される名称です。Google API では使用されない文字列です。いつでも更新できます。
  • プロジェクト ID は、すべての Google Cloud プロジェクトにおいて一意でなければならず、不変です(設定後は変更できません)。Cloud コンソールでは一意の文字列が自動生成されます。通常は、この内容を意識する必要はありません。ほとんどの Codelab では、プロジェクト ID(通常は PROJECT_ID と識別されます)を参照する必要があります。生成された ID が好みではない場合は、ランダムに別の ID を生成できます。または、ご自身で試して、利用可能かどうかを確認することもできます。このステップ以降は変更できず、プロジェクトを通して同じ ID になります。
  • なお、3 つ目の値として、一部の API が使用するプロジェクト番号があります。これら 3 つの値について詳しくは、こちらのドキュメントをご覧ください。
  1. 次に、Cloud のリソースや API を使用するために、Cloud コンソールで課金を有効にする必要があります。この Codelab の操作をすべて行って、費用が生じたとしても、少額です。このチュートリアルの終了後に請求が発生しないようにリソースをシャットダウンするには、作成したリソースを削除するか、プロジェクトを削除します。Google Cloud の新規ユーザーは、300 米ドル分の無料トライアル プログラムをご利用いただけます。

Cloud Shell を起動する

Google Cloud はノートパソコンからリモートで操作できますが、この Codelab では、Google Cloud Shell(Cloud 上で動作するコマンドライン環境)を使用します。

Google Cloud Console で、右上のツールバーにある Cloud Shell アイコンをクリックします。

55efc1aaa7a4d3ad.png

プロビジョニングと環境への接続にはそれほど時間はかかりません。完了すると、次のように表示されます。

7ffe5cbb04455448.png

この仮想マシンには、必要な開発ツールがすべて用意されています。永続的なホーム ディレクトリが 5 GB 用意されており、Google Cloud で稼働します。そのため、ネットワークのパフォーマンスと認証機能が大幅に向上しています。この Codelab での作業はすべて、ブラウザ内から実行できます。インストールは不要です。

3. はじめに

API を有効にする

Cloud Shell で、プロジェクト ID が設定されていることを確認します。

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 インスタンスを作成する

Vertex AI とデータベースを統合した Cloud SQL インスタンスを作成します。

データベース パスワードを作成する

デフォルトのデータベース ユーザーのパスワードを定義します。独自のパスワードを定義することも、乱数関数を使用してパスワードを生成することもできます。

export CLOUDSQL_PASSWORD=`openssl rand -hex 12`

生成されたパスワードの値をメモします。

echo $CLOUDSQL_PASSWORD

Cloud SQL for 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 のインテグレーションを有効にする

Vertex AI 統合を使用できるように、内部 Cloud SQL サービス アカウントに必要な権限を付与します。

Cloud SQL 内部サービス アカウントのメールアドレスを取得して、変数としてエクスポートします。

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

Cloud SQL サービス アカウントに Vertex AI へのアクセス権を付与します。

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

インスタンスの作成と構成の詳細については、こちらの Cloud SQL ドキュメントをご覧ください。

5. データベースを準備する

次に、データベースを作成してベクトルのサポートを有効にする必要があります。

データベースを作成

quickstart_db という名前のデータベースを作成します。これを行うには、mysql for mySQL、SDK、Cloud SQL Studio などのコマンドライン データベース クライアントなどのさまざまなオプションがあります。データベースの作成には SDK(gcloud)を使用します。

Cloud Shell でコマンドを実行してデータベースを作成します。

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

6. データの読み込み

次に、データベースにオブジェクトを作成し、データを読み込む必要があります。ここでは、架空の Cymbal ストアのデータを使用します。データは、SQL(スキーマ用)と CSV 形式(データ用)で使用できます。

Cloud Shell は、データベースに接続し、すべてのオブジェクトを作成し、データを読み込むためのメイン環境になります。

まず、Cloud Shell のパブリック IP を Cloud SQL インスタンスの承認済みネットワークのリストに追加する必要があります。Cloud Shell で、次のコマンドを実行します。

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 ユーティリティを使用します。

Cloud Shell で、次のコマンドを実行します。

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;"

独自のサンプルデータがあり、Cloud コンソールから利用できる Cloud SQL インポート ツールと互換性のある CSV ファイルがある場合は、ここで説明する方法の代わりに、そのツールを使用できます。

7. エンベディングを作成する

次のステップでは、Google Vertex AI の textembedding-005 モデルを使用して商品説明のエンベディングを作成し、テーブル 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);

2,000 行のベクトル エンベディングの生成には通常 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

データベース名と認証情報を指定するダイアログが開きます。

  • データベース: quickstart_db
  • ユーザー: student
  • Password: ユーザーのパスワード

[AUTHENTICATE] ボタンをクリックします。

36e6036847333d18.png

次のウィンドウが開きます。右側の [エディタ] タブをクリックして SQL エディタを開きます。

d803b7b6a798094f.png

これで、クエリを実行する準備が整いました。

クエリを実行

クエリを実行して、クライアントのリクエストに最も関連性の高い利用可能なプロダクトのリストを取得します。ベクトル値を取得するために Vertex AI に渡すリクエストは、「この地域でよく育つ果樹の種類」のようなものです。

cosine_distance 関数を使用してリクエストに最も適した最初の 5 つのアイテムを選択するには、次のクエリを実行します。

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 エディタに貼り付け、[実行] ボタンをクリックするか、quickstart_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 秒でした。

次に、approx_distance 関数を使用して 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 のレスポンスを改善する

実行されたクエリの結果を使用して、クライアント アプリケーションに対する生成 AI LLM の応答を改善し、Vertex AI 生成基盤言語モデルへのプロンプトの一部として提供されたクエリ結果を使用して、有意な出力を準備できます。

これを実現するには、ベクトル検索の結果を含む JSON を生成してから、生成された JSON を Vertex AI の LLM モデルのプロンプトに追加して、有意な出力を作成する必要があります。最初のステップでは JSON を生成してから Vertex AI Studio でテストし、最後のステップではアプリケーションで使用できる SQL ステートメントに組み込みます。

JSON 形式で出力を生成する

クエリを変更して、出力を JSON 形式で生成し、Vertex AI に渡す行を 1 つだけ返します。

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 の生成 AI テキストモデルにプロンプトの一部として提供できます。

Cloud コンソールで Vertex AI Studio Prompt を開きます。

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 を使用して生成 AI テキストモデルにプロンプトの一部として提供できます。

データベースへの 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. 最近傍インデックスを作成する

Google のデータセットは比較的小規模で、レスポンス時間は主に AI モデルとのやり取りに依存します。ただし、数百万ものベクトルがある場合、ベクトル検索にレスポンス時間の大部分が費やされ、システムに大きな負荷がかかります。これを改善するには、ベクトルの上にインデックスを構築します。

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 インスタンスを破棄する

接続が切断され、以前の設定がすべて失われた場合は、Cloud Shell でプロジェクトと環境変数を定義します。

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. 完了

以上で、この Codelab は完了です。

学習した内容

  • Cloud SQL for MySQL インスタンスをデプロイする方法
  • データベースを作成し、Cloud SQL AI インテグレーションを有効にする方法
  • データベースにデータを読み込む方法
  • Cloud SQL で Vertex AI エンベディング モデルを使用する方法
  • Vertex AI 生成モデルを使用して結果を拡充する方法
  • ベクトル インデックスを使用してパフォーマンスを改善する方法

同様の AlloyDB の Codelab または Cloud SQL for Postgres の Codelab をお試しください。

13. アンケート

出力:

このチュートリアルをどのように使用されますか?

全体を通して読むだけ 内容を読んで演習をやり遂げる