すべてのプロダクト
Search
ドキュメントセンター

PolarDB:冗長な GROUP BY/ORDER BY の削除

最終更新日:Jan 17, 2026

SQL クエリ内の冗長な GROUP BY 句または ORDER BY 句は、データベースに不要なソートまたはハッシュ操作を実行させます。これらの操作は、大量の CPU およびメモリリソースを消費し、特に大規模なデータセットを扱う場合に、分析処理 (AP) クエリのパフォーマンスに深刻な影響を与えます。PolarDB for MySQLGROUP BY/ORDER BY 削除機能は、関数従属性に基づいて、これらの冗長な操作を自動的に検出し、削除します。この機能は、アプリケーションコードを変更することなく、TPC-H ベンチマークで最大 29% の大幅なパフォーマンス向上を実現し、分析クエリのリソース消費を削減できます。

適用範囲

  • 製品シリーズ:Cluster EditionStandard Edition

  • バージョン:MySQL 8.0.2、リビジョン 8.0.2.2.33 以降。

削除機能の有効化

この最適化機能の動作は、loose_groupby_elimination_mode および loose_orderby_elimination_mode パラメーターを設定することで制御できます。

PolarDB クラスターのパラメーターを変更する方法は、コンソールとデータベースセッションで異なります。違いは次のとおりです:

  • PolarDB コンソール

    • 互換性:MySQL 設定ファイルとの互換性のため、PolarDB コンソールの一部のクラスターパラメーターには loose_ プレフィックスが付いています。

    • 手順loose_ プレフィックスが付いているパラメーターを見つけて変更します。

  • データベースセッション (コマンドラインまたはクライアントを使用)

    • 手順SET コマンドを使用してデータベースセッションでパラメーターを変更する場合は、loose_ プレフィックスを削除し、元のパラメーター名を使用します。

パラメーター名

レベル

説明

loose_groupby_elimination_mode

グローバル/セッション

GROUP BY 削除機能を制御します。有効な値は次のとおりです:

  • REPLICA_ON (デフォルト):読み取り専用 (RO) ノードでのみ機能を有効にします。

  • ON:有効。

  • オフ:システムの電源がオフになっています。

loose_orderby_elimination_mode

ORDER BY 削除機能を制御します。有効な値は次のとおりです:

  • REPLICA_ON (デフォルト):読み取り専用 (RO) ノードでのみ機能を有効にします。

  • ON:有効。

  • OFF:無効。

仕組み

GROUP BY/ORDER BY 削除機能は、関数従属性 (FD) を利用します。この機能の仕組みを理解することで、より良い SQL を記述し、最適化が適用されるかどうかを予測できます。

  • 関数従属性とは? 列 A (または列のセット) の値が列 B の値を一意に決定する場合、B は A に関数従属しています。この関係は A -> B と記述されます。例えば、ユーザーテーブルでは、プライマリキー user_idnickname を一意に決定します。したがって、関数従属性 user_id -> nickname が存在します。

  • オプティマイザーが関数従属性を見つける方法PolarDB オプティマイザーは、次のメタデータとクエリ条件から依存関係を自動的に推測します:

    • プライマリキーとユニークキー:テーブルスキーマで定義された PRIMARY KEY または UNIQUE KEY は、関数従属性の最も直接的なソースです。

    • 等価結合条件:プライマリキーの一意性は、JOIN 句の t1.pk = t2.fk などの等価結合条件を介して、関連テーブルに伝播できます。

    • 定数フィルター条件WHERE 句の WHERE status = 'active' などの等価フィルターは、結果セット内でその列を定数にします。

  • コア最適化ルール:

    • `GROUP BY` 削除

      • GROUP BY 句の列が、たとえばテーブルのプライマリキーを含むことによって、結果セットの各行をすでに一意に識別する場合、GROUP BY オペレーター全体は冗長であるため、安全に削除できます。

      • GROUP BY 句のすべての列が定数である場合、GROUP BY オペレーター全体を削除し、LIMIT 1 に置き換えることができます。

    • `ORDER BY` の削除: ORDER BY 句のすべての列が定数である場合、ORDER BY オペレーター全体は冗長であるため安全に削除できます。

    • `GROUP BY`/`ORDER BY` の簡略化: GROUP BY 句または ORDER BY 句の列間に、GROUP BY x, y における x -> y のように既知の関数従属性が存在する場合、その句を GROUP BY x に簡略化できます。これにより、グループ化またはソートに使用される列数が削減されます。

代表的な最適化シナリオと例

シナリオ 1:プライマリキーまたはユニークキーによるグループ化

GROUP BY 句にテーブルのプライマリキーまたは一意キーが含まれている場合、そのキーによってすでに一意の行が識別されるため、他の列でグループ化することは冗長です。

  • ビジネスシナリオ:各ユーザーの合計注文額を計算し、そのユーザー名を表示します。

  • 元の SQL

    -- user_id は user テーブルのプライマリキーであり、user_name を一意に決定します。
    SELECT
        u.user_id,
        u.user_name,
        COUNT(o.order_id)
    FROM user u
    JOIN orders o ON u.user_id = o.user_id
    GROUP BY
        u.user_id,
        u.user_name;
  • 最適化分析: user_id はプライマリキーであるため、user_name の値を一意に決定します。オプティマイザーは FD user_id -> user_name を検出し、GROUP BY u.user_id, u.user_nameGROUP BY u.user_id に自動的に簡略化します。これにより、user_name に対する不要なグループ化操作が排除されます。

シナリオ 2:定数によるグループ化

GROUP BY 句のすべてのカラムが定数である場合、結果セットに含まれる行は最大で 1 行になるため、グループ化操作全体が冗長になります。

  • ビジネスシナリオ:特定のユーザーの特定のステータス情報をクエリします。これは一般的ではない SQL パターンですが、オプティマイザーはこれを処理できます。

  • 元の SQL

    SELECT a, b FROM t1 WHERE a = 1 AND b = 1 GROUP BY a, b;
  • 最適化分析:オプティマイザーは、GROUP BY 句の列 abWHERE 句で定数として指定されていることを検出すると、GROUP BY オペレーターを削除し、LIMIT 1 を追加します。

    SELECT a, b FROM t1 WHERE a = 1 AND b = 1 LIMIT 1;

シナリオ 3:複数テーブル結合における複雑なグループ化 (TPC-H Q10)

複数テーブル JOIN を使用する複雑なクエリでは、関数従属性が結合条件を介して伝播されることがあります。オプティマイザーは、この伝播を使用して、より複雑で冗長なグループ化を排除します。

  • 元の SQL (TPC-H Q10)

    SELECT
        c_custkey, c_name, c_acctbal, c_phone, n_name, c_address, c_comment,
        SUM(l_extendedprice * (1 - l_discount)) AS revenue
    FROM customer, orders, lineitem, nation
    WHERE c_custkey = o_custkey
      AND l_orderkey = o_orderkey
      AND c_nationkey = n_nationkey
      -- その他のフィルター条件...
    GROUP BY
        c_custkey, c_name, c_acctbal, c_phone, n_name, c_address, c_comment
    ORDER BY revenue DESC
    LIMIT 20;
  • 最適化分析

    1. プライマリキー依存: customer テーブルでは、c_custkey がプライマリキーです。そのため、c_name, c_acctbal, c_phone, c_address, c_comment, and c_nationkey などの他のすべての列を⼀意に決定します。

    2. 依存関係の伝播: JOIN 条件は c_nationkey = n_nationkey です。n_nationkeynation テーブルのプライマリキーであり、n_name を決定するため、オプティマイザーは c_custkeyn_name を一意に決定すると推論できます。

    3. 最終的な単純化: 要約すると、GROUP BY 句の c_namec_acctbal などのすべての列は、c_custkey に対して関数従属です。したがって、オプティマイザーは複雑な GROUP BY リストを GROUP BY c_custkey に単純化します。これにより、グループ化の計算の複雑さが大幅に削減されます。

    SELECT 
       c_custkey, c_name, c_acctbal, c_phone, n_name, c_address, c_comment,
       SUM(l_extendedprice * (1 - l_discount)) AS revenue
    FROM customer, orders, lineitem, nation
    WHERE c_custkey = o_custkey
      AND l_orderkey = o_orderkey
      AND c_nationkey = n_nationkey
      -- その他のフィルター条件...
    GROUP BY c_custkey
    ORDER BY revenue DESC
    LIMIT 20;

シナリオ 4:ORDER BY のシナリオ

ORDER BY 句内の列の間に関数従属性が存在する場合、オプティマイザーはソートする列の数を減らすことでソート操作を簡略化できます。

  • ビジネスシナリオ:一部の列が他の列によって一意に決定されるテーブルをソートします。

  • テーブルスキーマ

    CREATE TABLE t1 (
      a int,
      b int,
      c int as (a + b) unique not null
    );
  • 元の SQL

    EXPLAIN SELECT a, b FROM t1 ORDER BY a,b,c;
  • 最適化分析: 列 c は、列 a および b から計算され (c = a + b)、unique not null として定義されているため、関数従属性 (a, b) -> c が存在します。オプティマイザーはこの従属性を認識し、ORDER BY a, b, c を自動的に ORDER BY a, b に簡略化することで、ソート操作の複雑さを軽減します。

    SHOW warnings;
    +-------+------+-------------------------------------------------------------------------------------------------------------------------------+
    | Level | Code | Message                                                                                                                       |
    +-------+------+-------------------------------------------------------------------------------------------------------------------------------+
    | Note  | 1003 | /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` order by `test`.`t1`.`a`,`test`.`t1`.`b` |
    +-------+------+-------------------------------------------------------------------------------------------------------------------------------+

パフォーマンステスト

TPC-H 100 GB 標準データセットでのテストでは、GROUP BY 削除機能を有効にすると、Q10 クエリのパフォーマンスが大幅に向上することが示されています。

説明
  • このトピックの TPC-H 実装は TPC-H ベンチマークに基づいており、公開されている TPC-H ベンチマーク結果と比較することはできません。このトピックで説明されているテストは、すべての TPC-H 要件に完全に準拠しているわけではありません。

  • 以下のデータは特定のシナリオでのテストによるものです。実際のパフォーマンス向上率は、クエリの複雑さ、データ分布、クラスターの仕様などの要因によって異なる場合があります。

テストシナリオ

GROUP BY 削除を有効にした場合 (実行時間)

無効にした場合 (実行時間)

パフォーマンスの向上

インメモリ列インデックス (IMCI) を 1 DOP で使用 (1 日以内のデータ生成)

48 秒

68 秒

29%

インメモリ列インデックス (IMCI) を 32 DOP で使用 (32 日以内のデータ生成)

1.9 秒

2.6 秒

27%