Tablestore SQL エンジンは、インデックス選択と計算プッシュダウンという 2 つのメカニズムを通じてクエリを最適化します。インデックス選択はデータソースを決定し、計算プッシュダウンは計算を実行する場所を決定します。
インデックス選択
データテーブルに セカンダリインデックス または 検索インデックス がある場合、SQL エンジンはクエリ実行前に最適なデータ読み取りパスを選択します。自動選択を使用するか、手動でインデックスを指定できます。
クエリ最適化を使用する前に、データテーブルマッピングが作成されていることを確認してください。詳細については、「DDL 操作」をご参照ください。検索インデックスを使用してクエリを高速化するには、検索インデックスとそのマッピングも作成する必要があります。
自動選択ルール
データテーブルマッピングをクエリすると、SQL エンジンは次の優先度に基づいてインデックスを自動的に選択します:
|
優先度 |
ターゲット |
条件 |
|
1 |
検索インデックス |
SELECT、WHERE、GROUP BY、および ORDER BY 句で参照されるすべての列が、同じ検索インデックスでカバーされていること。 例: |
|
2 |
セカンダリインデックス |
セカンダリインデックスが、データテーブルよりも WHERE 句の先頭のプライマリキー列に多く一致し (左端プレフィックスマッチング)、クエリ内のすべての列をカバーしていること。 例:データテーブルのプライマリキーが a と b であるとします。セカンダリインデックスのプライマリキーは c、a、b です。 |
|
3 |
CBO の決定 |
どちらのルールも適用されない場合、SQL エンジンは内部の CBO (コストベースオプティマイザ) を使用して、データテーブルとセカンダリインデックスの中からコストの低いオプションを選択します。 |
マッピングが強力な整合性で構成されている場合、または正確な集計結果が必要な場合、SQL エンジンは検索インデックスを自動的に選択しません。
セカンダリインデックスと検索インデックスの両方が必要なすべての列をカバーしている場合、SQL エンジンは検索インデックスを優先します。
インデックスの手動指定
特定のインデックスを使用するには、以下のいずれかの方法で手動で指定します:
USE INDEX 構文
SELECT ステートメントでインデックスを指定します。
-- フルテーブルスキャンを強制実行します (すべてのインデックスをスキップ)
SELECT * FROM sampletable use index();
-- 検索インデックスを使用します
SELECT * FROM sampletable use index(sampletable_search_index);
-- セカンダリインデックスを使用します
SELECT * FROM sampletable use index(sampletable_secondary_index);
指定されたインデックスが必要な列をカバーしていない場合、SQL エンジンは不足しているデータをデータテーブルから自動的に読み取ります。
インデックスマッピングテーブル
セカンダリインデックスまたは検索インデックスのマッピングテーブルを直接クエリします。
-- 検索インデックスマッピングテーブルを使用してクエリします (インデックス内の列のみクエリできます)
SELECT col_a, col_b FROM search_index_mapping WHERE col_a > 10;
インデックスマッピングテーブルに対するクエリは、インデックスに含まれている列のみを返すことができます。
推奨事項
|
シナリオ |
推奨事項 |
|
集計、ソート、または全文検索 |
自動選択 (デフォルト) を使用します。検索インデックスが必要なすべての列をカバーしていることを確認してください。SQL エンジンはクエリを自動的に検索インデックスにルーティングし、演算子をプッシュダウンします。 |
|
強力な整合性を伴う単純な等価フィルターまたは範囲フィルター |
セカンダリインデックスを使用します。セカンダリインデックスは、リアルタイムデータが必要な場合に、強力な整合性のある読み取りをサポートします。 |
|
自動選択で予期しない結果が生成される |
|
|
インデックス内の列のみが必要 |
データテーブルからの読み取りによるオーバーヘッドを回避するために、インデックスマッピングテーブルを直接クエリします。 |
計算プッシュダウン
SQL エンジンは、特定の演算子を検索インデックス層にプッシュダウンして、SQL エンジン層で処理されるデータ量を削減します。
有効化の条件
計算プッシュダウンを有効にするには、検索インデックスが SQL ステートメント内のすべての列 (SELECT、WHERE、ORDER BY、GROUP BY の列を含む) をカバーしている必要があります。検索インデックスに欠けている列がある場合、SQL エンジンはフルテーブルスキャンにフォールバックします。
-- テーブルには列 a、b、c、d があります。検索インデックスは a、b、c をカバーしています。
-- d は検索インデックスに含まれていないため → フルテーブルスキャンとなり、プッシュダウンは行われません
SELECT a, b, c, d FROM exampletable;
-- すべての列が検索インデックスに含まれているため → 検索インデックスを使用して読み取り、プッシュダウンがサポートされます
SELECT a, b, c FROM exampletable;
サポートされている演算子
|
演算子の種類 |
プッシュダウンのサポート |
条件 |
|
論理演算子 |
AND、OR、NOT |
|
|
関係演算子 |
=、!=、<、<=、>、>=、BETWEEN...AND |
列と定数の比較のみがサポートされています。検索インデックスは列ごとに独立したインデックスを構築するため、列間の比較はインデックス層で解決できず、プッシュダウンできません。 |
|
集計関数 |
MIN、MAX、COUNT、AVG、SUM、ANY_VALUE、COUNT(DISTINCT)、GROUP BY |
引数は列名である必要があり、式は使用できません。 |
|
ソートとページング |
ORDER BY col LIMIT n |
ORDER BY の引数は列名である必要があります。ORDER BY 内の式はプッシュダウンできません。 |
|
ベクトル関数 |
VECTOR_QUERY_FLOAT32 |
WHERE 句内の他のすべての式も、プッシュダウンの条件を満たす必要があります。いずれかの式が条件を満たさない場合、クエリは実行できません。 |
よくあるアンチパターン
|
アンチパターン |
修正パターン |
理由 |
|
|
列 a は BIGINT 型です。型の不一致により、暗黙的な CAST がトリガーされます。 |
|
|
集計の引数が式になっています。 |
|
|
GROUP BY の引数が式になっています。 |
|
同等の書き換えはありません。アプリケーション層でフィルターします。 |
列間の比較です。 |
|
|
ORDER BY の引数が式になっています。 |
SQL 式と検索インデックス機能とのマッピング
検索インデックス SDK から SQL クエリに移行するには、以下のテーブルを使用して、SQL 式を検索インデックスのクエリ機能に対応付けます。
|
SQL 式 |
例 |
検索インデックス機能 |
|
WHERE 句なし |
SELECT * FROM t |
|
|
= |
a = 1 |
|
|
>、>=、<、<= |
a > 1 |
|
|
IS NULL / IS NOT NULL |
a IS NULL |
|
|
AND / OR / NOT / != |
a = 1 AND b = 2 |
|
|
LIKE |
a LIKE "%s%" |
|
|
IN |
a IN (1,2,3) |
|
|
TEXT_MATCH |
TEXT_MATCH(a, "hello") |
|
|
TEXT_MATCH_PHRASE |
TEXT_MATCH_PHRASE(a, "hello world") |
|
|
ARRAY_EXTRACT |
ARRAY_EXTRACT(col) |
|
|
NESTED_QUERY |
NESTED_QUERY(expr) |
|
|
ORDER BY / LIMIT |
ORDER BY a LIMIT 10 |
|
|
集計関数 / GROUP BY |
SUM(col) / GROUP BY col |