Spanner クエリ オプティマイザーのバージョン

このページでは、Spanner のさまざまなクエリ オプティマイザーのバージョンについて説明し、その履歴を示します。現在のデフォルト バージョンは 7 です。クエリ オプティマイザーの詳細については、クエリ オプティマイザーについてをご覧ください。

Spanner では、クエリ オプティマイザーの更新が、新しいクエリ オプティマイザー バージョンとしてロールアウトされます。デフォルトでは、各データベースはリリースされてから 30 日以上経過した後にオプティマイザーの最新バージョンの使用を開始します。

GoogleSQL 言語データベースを使用している場合は、クエリで使用するクエリ オプティマイザーのバージョンを管理できます。最新バージョンに commit する前に、以前のバージョンと最新バージョンのクエリ パフォーマンス プロファイルを比較できます。詳細については、クエリ オプティマイザーを管理するをご覧ください。

クエリ オプティマイザーの変更履歴

以下は、各リリースでのクエリ オプティマイザーの更新の概要です。

バージョン 8: 2024 年 10 月 28 日(最新)

  • WITH 句は、費用ベースのプランを選択する際に考慮されます。

  • 分散クロス適用クエリとインデックス付きルックアップ クエリのパフォーマンスが向上しました。

  • JOIN の並べ替えを改善。

  • 大きな IN (...) 句を含むクエリのパフォーマンスが改善されました。

  • 特定のケースで GROUP BY のパフォーマンスを改善しました。

  • LIMIT を使用したクエリ、外部キー、インデックス選択の効率的な処理など、その他の改善。

バージョン 7: 2024 年 5 月 22 日(デフォルト)

  • インデックス ユニオン プランのコストベースの選択のサポートを追加しました。

  • すべてのキー部分にシーク可能な述語がないクエリの統計情報に基づいて、シークプランかスキャンプランの選択のサポートを追加しました。

  • ハッシュ結合のコストベースの選択のサポートを追加しました。

バージョン 6: 2023 年 9 月 11 日

  • 完全外部結合での制限の push と述語の push を改善しました。

  • カーディナリティの推定とコストモデルが改善されました。

  • DML クエリのコストベースの最適化を有効にしました。

バージョン 5: 2022 年 7 月 15 日

  • インデックスの選択、配布管理、並べ替えの配置、GROUP BY の選択にかかるコストモデルを改善しました。

  • ハッシュベースか適用結合かを選択する、コストベースの結合アルゴリズム選択のサポートを追加しました。クエリ結合は、引き続きクエリヒントを使用する必要があります。

  • コストベース結合の互換性のサポートを追加しました。

バージョン 4: 2022 年 3 月 1 日

  • セカンダリ インデックス選択の改善。

    • インターリーブされたテーブル間の結合でセカンダリ インデックスの使用を改善しました。
    • セカンダリ インデックスの使用方法を改善しました。
    • オプティマイザーの統計情報が古くなっているときのインデックスの選択を改善しました。
    • オプティマイザの統計情報が使用できない場合や、ベーステーブルが小さい場合でも、インデックス付けされた列の先頭に述語を含むセカンダリ インデックスを優先します。
  • 新しいヒント hash_join_execution により有効化された単一のパスハッシュ結合を導入しました。

    JOIN のヒント:

    GoogleSQL

    SELECT ...
    FROM (...)
    JOIN@{join_method=hash_join, hash_join_execution=one_pass} (...)
    

    PostgreSQL

    SELECT ...
    FROM (...)
    JOIN/*@ join_method=hash_join, hash_join_execution=one_pass */ (...)
    

    ハッシュ結合のビルドサイドの入力が大きい場合、新しいモードは有益です。クエリ実行プロファイルで以下を確認すると、1 つのパスハッシュ結合のパフォーマンス向上が期待されます。

    • ハッシュ結合の子に対する実行数が、ハッシュ結合演算子の実行数より大きい。
    • ハッシュ結合演算子の子であるレイテンシも長くなっている。

    デフォルト(hash_join_execution=multi_pass)では、ハッシュ結合のビルドサイドの入力がメモリに適合するには大きすぎる場合、ビルドサイドは複数のバッチに分割され、プローブ サイドが複数回スキャンされる場合があります。新しいモード(hash_join_execution=one_pass)を使用すると、ハッシュ結合は、そのビルドサイドの入力がメモリーに適合できない場合にディスクに分割され、プローブ サイドは常に 1 回だけスキャンされます。

  • シークに使用されるキー数の選択の改善。

バージョン 3: 2021 年 8 月 1 日

  • 新しい結合アルゴリズムのマージ結合を追加しました。新しい JOIN METHOD クエリヒント値を使用して有効にします。

    ステートメント ヒント:

    GoogleSQL

    @{join_method=merge_join}
    SELECT ...
    

    PostgreSQL

    /*@ join_method=merge_join */
    SELECT ...
    

    JOIN のヒント:

    GoogleSQL

    SELECT ...
    FROM (...)
    JOIN@{join_method=merge_join} (...)
    

    PostgreSQL

    SELECT ...
    FROM (...)
    JOIN/*@ join_method=merge_join */ (...)
    
  • 新しい結合アルゴリズムを追加し、プッシュ ブロードキャスト ハッシュ結合を追加しました。新しい JOIN METHOD クエリヒント値を使用して有効にします。

    JOIN のヒント:

    GoogleSQL

    SELECT ...
    FROM (...)
    JOIN@{join_method=push_broadcast_hash_join} (...)
    

    PostgreSQL

    SELECT ...
    FROM (...)
    JOIN/*@ join_method=push_broadcast_hash_join} */ (...)
    
  • 分散統合ユニオン演算子が導入されました。該当する場合はデフォルトで有効になります。このオペレーションにより、クエリのパフォーマンスが向上します。

  • SELECT リストに MAX または MIN の集計(または HAVING MAX/MAX)がない場合に、GROUP BY によるスキャンのパフォーマンスがわずかに改善されました。 この変更前は、Spanner はクエリで必要とされない場合でも、グループ化されていない余分な列を読み込んでいました。

    たとえば、次の表を検討します。

    GoogleSQL

    CREATE TABLE myTable(
      a INT64,
      b INT64,
      c INT64,
      d INT64)
    PRIMARY KEY (a, b, c);
    

    PostgreSQL

    CREATE TABLE myTable(
      a bigint,
      b bigint,
      c bigint,
      d bigint,
      PRIMARY KEY(a, b, c)
    );
    

    この変更前は、次のクエリでは列 c が読み込まれましたが、クエリでは必要ありませんでした。

    SELECT a, b
    FROM myTable
    GROUP BY a, b
    
  • 結合によって導入されたクロス アプライ演算子があり、クエリが LIMIT で並べ替えられた結果を要求する場合、LIMIT で一部のクエリのパフォーマンスを向上させます。この変更後、オプティマイザーはクロス アプライの入力側の制限を使用して並べ替えを最初に適用します。

    例:

    GoogleSQL

    SELECT a2.*
    FROM Albums@{FORCE_INDEX=_BASE_TABLE} a1
    JOIN Albums@{FORCE_INDEX=_BASE_TABLE} a2 USING(SingerId)
    ORDER BY a1.AlbumId
    LIMIT 2;
    

    PostgreSQL

    SELECT a2.*
    FROM albums/*@ force_index=_base_table */ a1
    JOIN albums/*@ force_index=_base_table */ a2 USING(singerid)
    ORDER BY a1.albumid
    LIMIT 2;
    
  • JOIN でより多くの計算を実行することで、クエリのパフォーマンスが改善されました。

    結合によるサブクエリまたは構造体の作成を含む、より多くの計算を push します。これにより、複数の方法でクエリのパフォーマンスが向上します。たとえば、より多くの計算を分散形式で実行でき、push される計算に依存するオペレーションもプッシュダウンできます。たとえば、クエリには上限があり、並べ替えの順序はこれらの計算に依存します。その後、結合を介して上限を push することもできます。

    例:

    SELECT
      t.ConcertDate,
      (
        SELECT COUNT(*) FROM UNNEST(t.TicketPrices) p WHERE p > 10
      ) AS expensive_tickets,
      u.VenueName
    FROM Concerts t
    JOIN Venues u ON t.VenueId = u.VenueId
    ORDER BY expensive_tickets
    LIMIT 2;
    

バージョン 2: 2020 年 3 月 1 日

  • インデックスの選択の最適化が追加されました。
  • 特定の状況で REGEXP_CONTAINSLIKE の述語のパフォーマンスが向上します。
  • 特定の状況で GROUP BY でのスキャンのパフォーマンスが向上します。

バージョン 1: 2019 年 6 月 18 日

  • 述語のプッシュダウン、制限のプッシュダウン、冗長結合、冗長な式の削除など、ルールベースの多数の最適化が含まれています。

  • ユーザーデータの統計情報を使用して、各テーブルへのアクセスに使用するインデックスを選択します。

次のステップ