Sign In
Free Sign Up
  • English
  • Español
  • 简体中文
  • Deutsch
  • 日本語
Sign In
Free Sign Up
  • English
  • Español
  • 简体中文
  • Deutsch
  • 日本語

MyScaleDBでベクトル検索のための複雑なSQLクエリを実行する方法

ベクトル検索は、ベクトル表現に基づいてデータセット内の類似ベクトルやデータポイントを検索する方法です。Pinecone、Milvus、Qdrant、Weaviateなどの専用のベクトルデータベースとは異なり、MyScaleDBはオープンソースのSQL互換データベースであるClickHouseをベースにしています。

Structured Query Language(SQL)は、リレーショナルデータベースの管理に効果的なツールです。MyScaleDBは、SQLとベクトルのパワーを組み合わせて、複雑なAI関連の問いに取り組むための強力な手法を提供します。ユーザーは、構造化データとベクトル埋め込み(データ)に対して従来のSQLクエリとベクトルクエリを実行し、複雑なクエリを処理し、高次元データを統一的かつ効率的に分析することができます。

このブログでは、まず最も人気のある高度なSQLテクニックについて説明します。次に、MyScaleDBが複雑なSQLクエリをベクトル検索と結合して単一のクエリで実行し、ClickHouseと共にクエリの実行を最適化し、データをより迅速かつ効率的に取得する方法を例示します。

# 複雑なクエリのための高度なSQLテクニック

シンプルなSQLクエリは、通常、1つのテーブルからデータを取得する単純なコマンドです。複雑なSQLクエリは、複数のテーブルからデータを取得し、複数の条件で結果セットを制限することで、標準的な要求を超えます。

複雑なクエリには、次のような特徴があります:

  • 共通テーブル式(CTE)
  • サブクエリ
  • 多くのテーブルを結合し、異なる結合タイプを使用する

# 共通テーブル式(CTE)

共通テーブル式(CTE)は、メインクエリ内のサブクエリに与える名前です。これを行う主な理由は、クエリを簡素化して読みやすくし、デバッグしやすくするためです。パフォーマンスの向上にも寄与することがありますが、主に読みやすさと簡素化に関わります。

特定の製品を購入した顧客の平均年齢を求めたい場合を考えてみましょう。顧客の名前、年齢、および購入した製品の情報を含む顧客データのテーブルがあるとします。

以下は、CTEを使用してこの計算を実行する例です:

WITH product_customers AS (
  SELECT name, age
  FROM customer_data
  WHERE product = 'widget'
)
SELECT AVG(age) AS avg_age
FROM product_customers;

このクエリでは、CTEという一時的な名前付き結果セット(サブクエリ)を使用しています。CTEの名前は「product_customers」です。これは、「customer_data」テーブルから「widget」という製品を購入した顧客の名前と年齢の列を取得する「SELECT」ステートメントを使用して作成されます。

サブクエリをクエリの先頭に移動し、名前を付けることで、クエリの動作が理解しやすくなります。サブクエリがサンプル埋め込みベクトルを選択する場合は、「target_vector_embed」といった名前を付けることができます。メインクエリでこれを参照すると、この名前が表示され、何を指しているのかがわかります。

また、長いクエリで同じロジックを複数の場所で必要とする場合にも役立ちます。クエリの先頭で定義し、メインクエリ全体で複数回参照することができます。

したがって、サブクエリがある場合は、CTEを使用してクエリの読みやすさを向上させることを検討してください。

# サブクエリ

サブクエリは、別のクエリ内に埋め込まれた単純なSQLコマンドです。クエリをネストすることで、結果セットに含まれるデータに対してより大きな制限を設定することができます。

サブクエリは、クエリ内のいくつかの場所で使用することができますが、最も簡単なのは「FROM」ステートメントから始めることです。基本的なサブクエリの例を示します:

SELECT sub.*
FROM (
  SELECT *
  FROM table
  WHERE conditions
) sub
WHERE sub.column_1 = 'MyScaleDB';

上記のクエリを実行する際に何が起こるかを見てみましょう:

まず、データベースは「内部クエリ」(括弧内の部分)を実行します。これを独立して実行すると、他のクエリと同様に結果セットが生成されます。内部クエリが実行された後、外部クエリが実行され、内部クエリの結果を基にしてテーブルが作成されます。

サブクエリには名前が必要であり、通常のテーブルにエイリアスを追加する方法と同じように、括弧の後に追加されます。このクエリでは、名前「sub」を使用しています。

# 条件付きロジックでのサブクエリの使用

サブクエリは、条件付きロジック(WHEREJOIN/ON、またはCASEと組み合わせて)で使用することができます。次のクエリは、データセット内の指定されたエントリと同じ日付のエントリをすべて返します:

SELECT *
FROM table
WHERE Date = (SELECT Date
              FROM table
              WHERE id='00001');

このクエリは、サブクエリの結果が1つのセルであるため動作します。ほとんどの条件付きロジックは、1つのセルの結果を含むサブクエリで動作します。ただし、INは、内部クエリに複数の結果が含まれる場合にのみ動作する条件付きロジックのタイプです:

SELECT *
FROM table
WHERE Date IN (SELECT Date
              FROM table
              ORDER BY Date
              LIMIT 5);

条件付きステートメント内でサブクエリを記述する際には、エイリアスを含めないように注意してください。これは、サブクエリがテーブルではなく個々の値(またはIN句の場合は値のセット)として扱われるためです。

# テーブルの結合

結合は、各テーブルに共通の値を使用して、1つまたは複数のテーブルから列を結合して新しいテーブルを作成します。結合の種類は次のとおりです:

  • INNER JOIN:一致するレコードのみが返されます。
  • LEFT JOIN:左側のテーブルのすべてのレコードと右側のテーブルの一致するレコードが返されます。
  • RIGHT JOIN:右側のテーブルのすべてのレコードと左側のテーブルの一致するレコードが返されます。
  • FULL JOIN:左側または右側のテーブルのいずれかに一致するレコードがある場合、両方のテーブルのすべてのレコードが返されます。
  • CROSS JOIN:テーブル全体の直積を生成します。結合キーが指定されていないため、すべての組み合わせが生成されます。
Boost Your AI App Efficiency now
Sign up for free to benefit from 150+ QPS with 5,000,000 vectors
Free Trial
Explore our product

# MyScaleDBでの複雑なSQLとベクトルクエリの使用

SQLベクトルデータベースであるMyScaleDBには、複雑なSQLとベクトルクエリをサポートするいくつかの機能があります。MyScaleDBの複雑なクエリの機能を示すいくつかの例を見てみましょう。

# 共通テーブル式(CTE)

MyScaleDBはCTEをサポートし、WITH句で定義されたコードをSELECTクエリの残りの部分に置き換えます。名前付きサブクエリは、現在のクエリと子クエリのコンテキストのどこでもテーブルオブジェクトが許可される場所に含めることができます。

ベクトル検索は、データをベクトルとして表現する検索方法です。画像検索、ビデオ検索、テキスト検索などのアプリケーションでよく使用されます。MyScaleDBでは、distance()関数を使用してベクトル検索を実行します。指定されたベクトルと指定された列内のすべてのベクトルデータとの距離を計算し、トップの候補を返します。

場合によっては、指定されたベクトルが別のテーブルから取得される場合や、指定されたベクトルの次元が大きく、表現が不便な場合には、CTEやサブクエリを使用することができます。

例えば、photoという名前のベクトルテーブルがあり、写真ライブラリの画像に関連するメタデータ情報をidphoto_idphoto_embedの列で保存しているとします。

次の例では、CTEで選択結果をターゲットベクトルとして扱い、ベクトル検索を実行しています:

WITH target_photo_embed AS (
  SELECT photo_embed
  FROM photos
  LIMIT 1)
SELECT id, photo_id, distance(photo_embed, target_photo_embed) as dist
FROM photos
ORDER BY dist
LIMIT 10;

# 結合とサブクエリ

結合のサポートは限定的であり、回避策としてサブクエリを使用することをお勧めします。MyScaleDBでは、ベクトル検索はベクトル列を持つテーブル上のベクトルインデックスに基づいています。distance()関数はSELECT句に表示されますが、その値は結合後ではなく、テーブル上のベクトル検索時に計算されます。結合結果は期待される結果とは異なる場合があります。

以下は、可能な回避策です:

  • ベクトルテーブルを利用したサブクエリ内でdistance()...WHERE...ORDER BY...LIMITクエリパターンを使用し、ベクトルテーブル上で期待される結果を得ることができます。

  • サブクエリをWHERE句で使用して結合を書き換えることもできます。

例えば、別のテーブルphoto_metaがあり、写真ライブラリの画像に関する情報をphoto_idphoto_authoryeartitleの列で保存しているとします。次の例では、画像のコレクションから2023年に撮影された関連する写真を取得しています:

SELECT t1.photo_id, distance(t1.photo_embed,[0.0269, 0.0316,...]) as dist
FROM photos t1
JOIN photo_meta t2 ON t1.photo_id = t2.photo_id
WHERE t2.year = 2023
ORDER BY dist
LIMIT 5;

上記のクエリを実行すると、次のような結果が得られます:

まず、MyScaleDBはテーブルphotos上でベクトル検索を実行し、トップ5の関連レコードの必要な列photo_iddistance()関数の値を取得します:

SELECT photo_id, distance(photo_embed,[0.0269, 0.0316,...]) as dist
FROM photos
ORDER BY dist
LIMIT 5;

次に、ベクトルテーブルの結果を基にしてjoinが実行されます:

SELECT t1.photo_id, t1.dist
FROM (<<ベクトルテーブルの結果がここに入る>>)t1
JOIN photo_meta t2 ON t1.photo_id = t2.photo_id
WHERE t2.year = 2023;

ベクトル検索は写真が撮影された年を考慮しないため、結果は正しくない場合があります。正しい結果を得るためには、サブクエリを使用して結合クエリを書き換える必要があります:

SELECT t1.photo_id, t1.dist
FROM (
  SELECT photo_id, distance(photo_embed,[0.0269, 0.0316,...]) as dist
  FROM photos
  WHERE photo_id IN (
    SELECT t1.photo_id
    FROM photos t1 JOIN photo_meta t2 ON t1.photo_id = t2.photo_id
    WHERE t2.year = 2023)
  ORDER BY dist
  LIMIT 5
) t1
ORDER BY dist
LIMIT 5;
Join Our Newsletter

# データ分析の改善

CTE、サブクエリ、結合などの高度なSQLテクニックを使用すると、より正確かつ効率的に複雑なデータ分析や操作を行うことができます。MyScaleDBは、SQLとベクトルのパワーを組み合わせて、複雑なAI関連の問いに取り組むための強力な手法を提供します。MyScaleDBを使用すると、構造化データとベクトルデータ上で従来のSQLクエリとベクトルクエリを効率的に実行し、複雑なクエリに対応し、高次元データを統一的かつ効率的に分析することができます。

詳細については、X(Twitter) (opens new window)でフォローするか、Discord (opens new window)コミュニティに参加してください。一緒にデータとAIの未来を築きましょう!

Keep Reading
images
マイスケールにおけるハイブリッド検索のマスタリング:包括的なガイド

ハイブリッド検索は、複数の検索アルゴリズムを統合することで、検索結果の正確性と関連性を高める強力な技術です。全文検索とベクトル検索の強みを組み合わせることで、ハイブリッド検索はより効果的で包括的なユーザー検索体験を提供します。 MyScaleDBのバージョン1.6.2では、このハイブリッド検索機能が導入さ ...

images
Triplet Lossとは

コントラスティブ学習の前回の探求では、モデルが埋め込み空間で似たデータと異なるデータを区別する方法を明らかにしました。似たアイテムを近くに配置し、異なるアイテムを遠くに押し出すことで、モデルは学習します。[SimCLR](https://myscale.com/blog/ja/ ...

Start building your Al projects with MyScale today

Free Trial
Contact Us