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

PolarDB:派生テーブルとビューのカラムプルーニング最適化

最終更新日:Dec 14, 2025

多くのカラムを持つ派生テーブルやビューから、クエリが一部のカラムのみを選択すると、パフォーマンスが低下する可能性があります。これは、クエリが不要なデータを読み取り、処理するために発生します。この問題は、ワイドテーブルを扱う場合や、大規模で汎用的なビューを再利用する場合によく発生します。PolarDB for MySQL のカラムプルーニング機能は、これらのクエリを自動的に最適化します。クエリ解析フェーズにおいて、オプティマイザーは、最終的なクエリで使用されない派生テーブルまたはビューのカラムを特定し、削除します。これにより、スキャンされるデータ量、ネットワーク転送、メモリ消費量が大幅に削減されます。また、クエリレイテンシーが短縮され、システムスループットが向上します。

適用範囲

  • 製品シリーズ:Cluster EditionStandard Edition

  • カーネルバージョン:MySQL 8.0.2、リビジョンバージョン 8.0.2.2.31.1 以降。

カラムプルーニングの有効化

loose_derived_table_pruning_mode パラメーターを設定することで、この最適化機能の動作を制御できます。

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

  • PolarDB コンソール

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

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

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

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

パラメーター

レベル

説明

loose_derived_table_pruning_mode

グローバル/セッション

この機能のメインスイッチです。有効な値は次のとおりです:

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

  • ON:この機能を有効にします。

  • OFF:この機能を無効にします。

仕組みと例

カラムプルーニング最適化のコアは、クエリの再書き込みです。クエリの論理的最適化フェーズにおいて、オプティマイザーは検索ステートメント全体を分析します。最終的な SELECT リスト、WHERE 句、または JOIN 句で参照されていない派生テーブルまたはビューのカラムを特定します。カラムが冗長である場合、オプティマイザーは内部クエリを再書き込みます。これにより、ソースでのカラムデータの読み取りと処理が回避され、I/O と CPU 消費量が削減されます。

例1:派生テーブルクエリの最適化

この例では、カラムプルーニングが派生テーブルに対するクエリをどのように最適化するかを示します。

-- 最適化前
SELECT c1 FROM (SELECT c1 FROM (SELECT c1, c2 FROM t1 GROUP BY c1, c2) v) t;
-- 最適化後
SELECT c1 FROM (SELECT c1 FROM t1 GROUP BY c1, c2) v
  1. テストデータの準備:ご利用のデータベースに複数のカラムを持つ t1 という名前のテーブルを作成します。

    CREATE TABLE t1 (id INT PRIMARY KEY, c1 INT, c2 INT, c3 VARCHAR(100));
    INSERT INTO t1 VALUES (1, 10, 100, 'data'), (2, 20, 200, 'data');
  2. 最適化を無効にしてクエリを実行:まず、セッションでカラムプルーニング機能を無効にして、最適化前の実行計画を確認します。

    SET derived_table_pruning_mode = 'OFF';
    EXPLAIN SELECT c1 FROM (SELECT c1 FROM (SELECT c1, c2 FROM t1 GROUP BY c1, c2) v) t;
    SHOW warnings;
    
    +-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Level | Code | Message                                                                                                                                                                                         |
    +-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Note  | 1003 | /* select#1 */ select `v`.`c1` AS `c1` from (/* select#3 */ select `testdb`.`t1`.`c1` AS `c1`,`testdb`.`t1`.`c2` AS `c2` from `testdb`.`t1` group by `testdb`.`t1`.`c1`,`testdb`.`t1`.`c2`) `v` |
    +-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  3. 最適化を有効にしてクエリを実行:次に、セッションでカラムプルーニング機能を有効にし、同じクエリを実行します。

    SET derived_table_pruning_mode = 'ON';
    EXPLAIN SELECT c1 FROM (SELECT c1 FROM (SELECT c1, c2 FROM t1 GROUP BY c1, c2) v) t;
    SHOW warnings;
    
    +-------+------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Level | Code | Message                                                                                                                                                              |
    +-------+------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Note  | 1003 | /* select#1 */ select `v`.`c1` AS `c1` from (/* select#3 */ select `testdb`.`t1`.`c1` AS `c1` from `testdb`.`t1` group by `testdb`.`t1`.`c1`,`testdb`.`t1`.`c2`) `v` |
    +-------+------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+

    実行計画の解釈:最適化後、実行計画は大幅に変わります。オプティマイザーは、外部クエリが c1 カラムのみを必要とすることを検出し、クエリを再書き込みます。

例2:ビュークエリの最適化

ビューのカラムプルーニングは、派生テーブルの場合と似ています。不要な計算を回避します。

CREATE VIEW v1 AS SELECT COUNT(*) AS a, (SELECT a FROM t2 WHERE a=FLOOR(COUNT(t1.a)/2)) AS s FROM t1;

-- 最適化前
SELECT a FROM v1;
-- 最適化後
SELECT COUNT(*) AS a FROM t1;

最適化の制限

カラムプルーニング最適化は、再書き込みされたクエリが元の SQL 文と意味的に等価であることが保証されている場合にのみトリガーされます。参照されていないように見える派生テーブルまたはビューのカラムでも、次のいずれかの操作で使用されている場合はプルーニングされません:

  • ORDER BYGROUP BYHAVING、または DISTINCT 句で使用されている場合。

  • ウィンドウ関数でパーティションキー (PARTITION BY) またはソートキー (ORDER BY) として使用されている場合。

  • オプティマイザーは、RAND()UUID() などの非決定性関数によって生成されたカラムをプルーニングできます。この場合、関数は実行されず、不要な計算オーバーヘッドが回避されます。この動作は、制限ではなく、意図された最適化効果です。

よくある質問

derived_table_pruning_mode パラメーターの変更にはクラスターの再起動が必要ですか?

いいえ、必要ありません。このパラメーターは動的に変更でき、再起動なしで即座に有効になります。

プライマリノードで derived_table_pruning_mode=ON を設定した後、クエリのパフォーマンスが向上しないのはなぜですか?

  1. SQL シナリオの確認:ご利用の SQL 文がカラムプルーニングの条件を満たしていることを確認してください。外部クエリは、内部の派生テーブルまたはビューのカラムのサブセットのみを使用する必要があります。

  2. 実行計画の表示EXPLAIN を使用して、最適化が行われたかどうかを確認します。行われなかった場合は、「最適化の制限」セクションを参照して、プルーニングが適用されないシナリオを確認してください。