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

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

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

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

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

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

バージョン 6: 2023 年 9 月 11 日(最新とデフォルト)

  • 完全外部結合による制限 push と述語 push が改善されました。

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

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

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

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

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

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

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

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

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

    JOIN のヒント:

    Google SQL

    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 クエリヒント値を使用して有効にします。

    ステートメント ヒント:

    Google SQL

    @{join_method=merge_join}
    SELECT ...
    

    PostgreSQL

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

    JOIN のヒント:

    Google SQL

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

    PostgreSQL

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

    JOIN のヒント:

    Google SQL

    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 はクエリで必要とされない場合でも、グループ化されていない余分な列を読み込んでいました。

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

    Google SQL

    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 で一部のクエリのパフォーマンスを向上させます。この変更後、オプティマイザーはクロス アプライの入力側の制限を使用して並べ替えを最初に適用します。

    例:

    Google SQL

    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 日

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

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

次のステップ