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

PolarDB:SQL クエリを高速化するために IMCI を使用するかどうかの判断に EXPLAIN ステートメントを使用する

最終更新日:Mar 13, 2025

このトピックでは、EXPLAIN ステートメントを使用して、インメモリ列インデックス (IMCI) を使用して SQL クエリを高速化するかどうかを判断する方法について説明します。

PolarDB for MySQL クラスタでは、列形式のデータに対するクエリの execution plan は、行ベース形式のデータに対するクエリの execution plan の出力形式とは異なる、水平ツリー形式で表示されます。 EXPLAIN ステートメントを実行して、SQL クエリの PolarDB for MySQL を表示し、IMCI を使用してクエリを高速化するかどうかを判断できます。

SQL クエリの例:

EXPLAIN SELECT l_orderkey, SUM(l_extendedprice * (1 - l_discount)) AS revenue, o_orderdate, o_shippriority
FROM customer, orders, lineitem
WHERE c_mktsegment = 'BUILDING'
AND c_custkey = o_custkey
AND l_orderkey = o_orderkey
AND o_orderdate < date '1995-03-24'
AND l_shipdate > date '1995-03-24'
GROUP BY l_orderkey, o_orderdate, o_shippriority
ORDER BY revenue DESC, o_orderdate;

クエリ対象のデータが行ベース形式の場合の実行計画:

+----+-------------+----------+------------+------+--------------------+------------+---------+-----------------------------+--------+----------+----------------------------------------------+
| id | select_type | table    | partitions | type | possible_keys      | key        | key_len | ref                         | rows   | filtered | Extra                                        |
+----+-------------+----------+------------+------+--------------------+------------+---------+-----------------------------+--------+----------+----------------------------------------------+
|  1 | SIMPLE      | customer | NULL       | ALL  | PRIMARY            | NULL       | NULL    | NULL                        | 147630 |    10.00 | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | orders   | NULL       | ref  | PRIMARY,ORDERS_FK1 | ORDERS_FK1 | 4       | tpch100g.customer.C_CUSTKEY |     14 |    33.33 | Using where                                  |
|  1 | SIMPLE      | lineitem | NULL       | ref  | PRIMARY            | PRIMARY    | 4       | tpch100g.orders.O_ORDERKEY  |      4 |    33.33 | Using where                                  |
+----+-------------+----------+------------+------+--------------------+------------+---------+-----------------------------+--------+----------+----------------------------------------------+
3 rows in set, 1 warning (0.00 sec)

クエリ対象のデータが列形式の場合の実行計画 (水平ツリー形式):

+----+----------------------------+----------+--------+--------+-----------------------------------------------------------------------------+
| ID | Operator                   | Name     | E-Rows | E-Cost | Extra Info                                                                  |
+----+----------------------------+----------+--------+--------+-----------------------------------------------------------------------------+
|  1 | Select Statement           |          |        |        | IMCI Execution Plan (max_dop = 4, max_query_mem = 858993459)                |
|  2 | └─Sort                     |          |        |        | Sort Key: revenue DESC,o_orderdate ASC                                      |
|  3 |   └─Hash Groupby           |          |        |        | Group Key: (lineitem.L_ORDERKEY, orders.O_ORDERDATE, orders.O_SHIPPRIORITY) |
|  4 |     └─Hash Join            |          |        |        | Join Cond: orders.O_ORDERKEY = lineitem.L_ORDERKEY                          |
|  5 |       ├─Hash Join          |          |        |        | Join Cond: customer.C_CUSTKEY = orders.O_CUSTKEY                            |
|  6 |       │ ├─Table Scan       | customer |        |        | Cond: (C_MKTSEGMENT = "BUILDING")                                           |
|  7 |       │ └─Table Scan       | orders   |        |        | Cond: (O_ORDERDATE < 03/24/1995)                                            |
|  8 |       └─Table Scan         | lineitem |        |        | Cond: (L_SHIPDATE > 03/24/1995)                                             |
+----+----------------------------+----------+--------+--------+-----------------------------------------------------------------------------+
8 rows in set (0.01 sec)

関連情報

IMCI は、IMCI がカバーする列にのみアクセスできます。 SQL statement で参照されているテーブルまたは列が IMCI で完全にカバーされていない場合、IMCI は有効になりません。

  • SQL statement で参照されているテーブルに IMCI が作成されているかどうかを確認するには、dbms_imci.check_columnar_index() ストアドプロシージャを呼び出します。このストアドプロシージャは、入力した SQL statement を解析し、statement で参照されているすべての列を取得し、それらの列が IMCI でカバーされているかどうかを確認できます。詳細については、「SQL ステートメントのテーブルに IMCI が作成されているかどうかの確認」をご参照ください。

  • IMCI の作成に使用された DDL statement を取得するには、dbms_imci.columnar_advise() ストアドプロシージャを呼び出します。このストアドプロシージャは、入力した SQL statement に基づいて、IMCI の作成に使用された DDL statement を返すことができます。詳細については、「IMCI の作成に使用された DDL ステートメントの取得」をご参照ください。 DDL statement を実行すると、SQL statement で参照されているすべての列をカバーする IMCI が作成されます。

よくある質問

SQL クエリが高速化に IMCI を使用しないのはなぜですか?

SQL クエリが IMCI を使用して高速化されるのは、次の条件がすべて満たされている場合のみです。読み取り専用の列ストア ノードがクラスターに追加されている。SQL クエリに関連するテーブルに IMCI が作成されている。[推定実行コスト] が指定されたしきい値を超えている。SQL クエリが読み取り専用の列ストア ノードに転送される。SQL クエリが IMCI を使用しない場合は、次の手順を実行して問題のトラブルシューティングを行うことができます。

  1. SQL クエリが読み取り専用の列ストアノードに転送されているかどうかを確認します。

    • 読み取り専用の列ストアノードが、クラスタエンドポイントの [選択済みノード] に含まれているかどうかを確認します。

    • SQL エクスプローラー機能を使用して、SQL クエリが読み取り専用の列ストアノードに転送されているかどうかを確認します。詳細については、「SQL エクスプローラー」をご参照ください。

    PolarProxy は、次の条件がすべて満たされた場合にのみ、SQL クエリを 読み取り専用 列ストア ノードに転送します。SQL クエリが [クラスターエンドポイント] を使用してクラスターにアクセスしていること、[トランザクション/分析処理分割] がクラスターエンドポイントに対して有効になっていること、および SQL クエリの推定実行コストloose_imci_ap_threshold パラメーターまたは loose_cost_threshold_for_imci パラメーターで指定されたしきい値を超えていることです。SELECT キーワードの前に /*FORCE_IMCI_NODES*/ ヒントを追加することで、SQL 文を 読み取り専用 列ストア ノードに強制的に転送できます。詳細については、「自動リクエスト分散のしきい値を指定する」をご参照ください。例:

    loose_imci_ap_threshold パラメーターは、マイナーバージョンが 8.0.1.1.39 以降、または 8.0.2.2.23 以降のデータベースエンジンでは、loose_cost_threshold_for_imci パラメーターの代わりに使用されます。
    /*FORCE_IMCI_NODES*/EXPLAIN SELECT COUNT(*) FROM t1 WHERE t1.a > 1;
    カスタムエンドポイントを作成し、そのエンドポイントを読み取り専用の列ストアノードに関連付けることができます。これにより、SQL クエリが読み取り専用の列ストアノードに転送されて実行されることが保証されます。詳細については、「行ストアノードと列ストアノード間での HTAP ベースのリクエスト配信」をご参照ください。
  2. 推定実行コスト が指定されたしきい値を超えているかどうかを確認します。

    列ストア ノードでは、オプティマイザーが SQL クエリの推定実行コストを計算します。SQL クエリの推定実行コストが、loose_imci_ap_threshold パラメーターまたは cost_threshold_for_imci パラメーターで指定されたしきい値よりも高い場合、オプティマイザーはクエリで IMCI を使用します。それ以外の場合、オプティマイザーはクエリで元の行インデックスを使用します。

    EXPLAIN 文で、SQL クエリが読み取り専用列ストア ノードに転送された後も実行計画で IMCI が使用されていないことが示されている場合は、推定実行コストを指定のしきい値と比較して、推定実行コストが小さすぎるために IMCI が使用されていないかどうかを判断します。Last_query_cost 値をクエリして、前の SQL 文の 推定実行コストを取得できます。例:

    -- EXPLAIN 文を実行して、SQL クエリの 実行計画 を表示します。
    EXPLAIN SELECT * FROM t1;
    -- 直前の SQL クエリの推定実行コストを取得します。
    SHOW STATUS LIKE 'Last_query_cost';
    クラスターエンドポイントを使用してクラスターに接続する場合は、/*ROUTE_TO_LAST_USED*/ ヒントを SHOW STATUS LIKE 'Last_query_cost' 文の前に追加することをお勧めします。これにより、前の 推定実行コスト が正しいノードで見つかるようになります。例: /*ROUTE_TO_LAST_USED*/SHOW STATUS LIKE 'Last_query_cost';

    SQL クエリの 推定実行コスト が指定されたしきい値未満の場合、loose_imci_ap_threshold または loose_cost_threshold_for_imci の値を調整できます。HINT を使用して、単一の SQL クエリのしきい値を調整することもできます。例:

    /*FORCE_IMCI_NODES*/EXPLAIN SELECT /*+ SET_VAR(cost_threshold_for_imci=0) */ COUNT(*) FROM t1 WHERE t1.a > 1;
  3. SQL クエリに関連するテーブルまたは列が IMCI に完全に含まれているかどうかを確認します。

    組み込みストアドプロシージャ dbms_imci.check_columnar_index('<query_string>') を呼び出して、SQL statement のテーブルまたは列に IMCI が作成されているかどうかを確認できます。詳細については、「SQL ステートメントのテーブルに IMCI が作成されているかどうかの確認」をご参照ください。例:

    CALL dbms_imci.check_columnar_index('SELECT COUNT(*) FROM t1 WHERE t1.a > 1');

    SQL クエリに関連するテーブルまたは列が IMCI に完全に含まれていない場合、ストアドプロシージャは IMCI に含まれていないテーブルと列を返します。この場合は、返されたテーブルと列に IMCI を作成する必要があります。 SQL クエリに関連するテーブルまたは列が IMCI に完全に含まれている場合、ストアドプロシージャは空の結果セットを返します。

  4. SQL クエリが IMCI をサポートしているかどうかを確認します。

    IMCI の使用制限を表示して、SQL クエリが IMCI をサポートしているかどうかを判断します。詳細については、「IMCI の使用制限」をご参照ください。

SQL クエリで IMCI がまだ使用されていない場合は、専門家 に相談するか、お問い合わせ ください。

SQL クエリに適した IMCI を作成するにはどうすればよいですか?

SQL クエリに関連する列に基づいて IMCI を作成することをお勧めします。詳細については、「SQL ステートメントのテーブルに IMCI が作成されているかどうかの確認」をご参照ください。

SQL クエリは、IMCI に SQL クエリに関連するすべての列が含まれている場合にのみ、IMCI を使用します。 SQL クエリに関連する列が IMCI で完全にカバーされていない場合は、ALTER TABLE statement を使用して IMCI を追加できます。 PolarDB は、この操作を支援するための組み込みストアドプロシージャを提供しています。

説明
  • dbms_imci.columnar_advise() ストアドプロシージャを使用して、SQL クエリに IMCI を作成するために使用される DDL statement を取得できます。 DDL statement を使用して IMCI を作成すると、SQL クエリに関連する列が IMCI に完全に含まれるようになります。詳細については、「IMCI の作成に使用された DDL ステートメントの取得」をご参照ください。

    dbms_imci.columnar_advise('<query_string>');
  • 次のストアドプロシージャを使用して、一連の SQL クエリに IMCI を作成するために使用される DDL statement を取得できます。 dbms_imci.columnar_advise_begin()dbms_imci.columnar_advise_end()dbms_imci.columnar_advise()。詳細については、「IMCI を作成するために使用される DDL ステートメントのバッチ取得」をご参照ください。