多くのカラムを持つ派生テーブルやビューから、クエリが一部のカラムのみを選択すると、パフォーマンスが低下する可能性があります。これは、クエリが不要なデータを読み取り、処理するために発生します。この問題は、ワイドテーブルを扱う場合や、大規模で汎用的なビューを再利用する場合によく発生します。PolarDB for MySQL のカラムプルーニング機能は、これらのクエリを自動的に最適化します。クエリ解析フェーズにおいて、オプティマイザーは、最終的なクエリで使用されない派生テーブルまたはビューのカラムを特定し、削除します。これにより、スキャンされるデータ量、ネットワーク転送、メモリ消費量が大幅に削減されます。また、クエリレイテンシーが短縮され、システムスループットが向上します。
適用範囲
製品シリーズ:Cluster Edition、Standard Edition。
カーネルバージョン:MySQL 8.0.2、リビジョンバージョン 8.0.2.2.31.1 以降。
カラムプルーニングの有効化
loose_derived_table_pruning_mode パラメーターを設定することで、この最適化機能の動作を制御できます。
PolarDB クラスターのパラメーターを変更する方法は、コンソールとデータベースセッションで異なります。違いは次のとおりです:
互換性:MySQL 設定ファイルとの互換性のため、PolarDB コンソールの一部のクラスターパラメーターには loose_ プレフィックスが付いています。
手順:
loose_プレフィックスが付いているパラメーターを見つけて変更します。
データベースセッション内 (コマンドラインまたはクライアントを使用)
手順:
SETコマンドを使用してデータベースセッションでパラメーターを変更する場合、loose_プレフィックスを削除し、元のパラメーター名を使用します。
パラメーター | レベル | 説明 |
| グローバル/セッション | この機能のメインスイッチです。有効な値は次のとおりです:
|
仕組みと例
カラムプルーニング最適化のコアは、クエリの再書き込みです。クエリの論理的最適化フェーズにおいて、オプティマイザーは検索ステートメント全体を分析します。最終的な 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テストデータの準備:ご利用のデータベースに複数のカラムを持つ
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');最適化を無効にしてクエリを実行:まず、セッションでカラムプルーニング機能を無効にして、最適化前の実行計画を確認します。
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` | +-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+最適化を有効にしてクエリを実行:次に、セッションでカラムプルーニング機能を有効にし、同じクエリを実行します。
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 BY、GROUP BY、HAVING、またはDISTINCT句で使用されている場合。ウィンドウ関数でパーティションキー (
PARTITION BY) またはソートキー (ORDER BY) として使用されている場合。オプティマイザーは、
RAND()やUUID()などの非決定性関数によって生成されたカラムをプルーニングできます。この場合、関数は実行されず、不要な計算オーバーヘッドが回避されます。この動作は、制限ではなく、意図された最適化効果です。