POLARDB for MySQL 8.0 は、並列クエリフレームワークを起動します。 クエリされたデータ量が特定のしきい値に達すると、並列クエリフレームワークが自動的に有効になります。 これにより、クエリの実行に必要な時間が大幅に短縮されます。

ストレージ層では、データは異なるスレッドに分割されます。 複数のスレッドが並列計算を実行し、結果をリーダースレッドに返します。 最後に、リーダースレッドは結果の単純なマージを実行し、最終結果をユーザーに返します。 これにより、クエリの速度と精度が向上します。

並列クエリは、マルチコア CPU の並列処理機能を使用して実現されます。 次の図は、8 コア CPU と 32 GB のメモリを備えたノードで並列処理がどのように機能するかを示します。

示意图

シナリオ

並列クエリは、大規模なテーブルに対するクエリ、JOIN を使用するマルチテーブルクエリ、大量の計算を必要とするクエリなど、ほとんどの SELECT ステートメントに適用できます。 並列クエリの効果は、短いクエリでは重要ではありません。

  • 軽量分析業務

    通常、レポートクエリは複雑で時間がかかります。 並列クエリを有効にすると、単一クエリを高速化できます。

  • より多くシステムリソースが利用可能

    並列クエリは、より多くのシステムリソースを消費します。 システムに多くの CPU リソースがあり、I / O 負荷が低く、十分なメモリがある場合のみ。

パフォーマンス上の利点

詳細については、「並列クエリの例」をご参照ください。

並列クエリの使用方法

  • システムパラメーターを使用して並列クエリを制御する

    POLARDB は、グローバルパラメーター max_parallel_degree を使用して、各 SQL ステートメントの並列処理に使用できるスレッドの最大数を制御します。 デフォルト値は 4 です。 パラメーター値は、データベースを再起動しなくても、使用中にいつでも変更できます (クラスターパラメータの設定参照).。

    グローバルパラメーターを変更してクラスターレベルの並列度 (DOP) を変更するだけでなく、特定のセッションで SQL クエリの DOP を調整することもできます。 たとえば、JDBC 接続文字列の設定にセッションレベルの環境変数を追加すると、特定のアプリケーションの DOP を設定できます。
    max_parallel_degree = n に設定 
  • ヒントを使用する
    ヒントを使用して並列クエリを有効化します (n は最も高い DOP、つまりワーカーの最大数を表します):
     SELECT /*+ SET_VAR(max_parallel_degree=n) */  *  FROM ...
    最適なパフォーマンスを実現するために、並列クエリはすべての SQL ステートメントに影響するわけではありません。 POLARDB オプティマイザーは、特定の SQL ステートメントに基づいて効率的なクエリプランを生成できます。
  • オプティマイザーに強制的に並列実行を選択させる
    POLARDB オプティマイザーはクエリを並行して実行しない場合があります。 ただし、コストを無視して、オプティマイザーがほとんどのケースで並列スケジューリングを選択するようにしたい場合は、以下のパラメーターを設定することができます。
    force_parallel_mode = on に設定します
    これはデバッグパラメーターです。 本番環境ではこのエディションを使用しないことを推奨します。 並列クエリの制限により、このパラメーターが設定されていても、オプティマイザーがクエリを並列で実行できない場合があります。

パラメーターと変数

パラメーター レベル 説明
max_parallel_degree セッションとグローバル

単一クエリの最大 DOP、つまり、クエリを並列実行するために使用されるワーカーの最大数。

  • 有効値: 0~1024。 値が 0 の場合は、並列計算が無効であることを示します。
  • デフォルト値:0
POLARDB オプティマイザーは、メインクエリとサブクエリを並行して実行できます。 クエリが並列で実行される場合、ワーカーの最大数は max_parallel_degree の値を超えることはできません。 ワーカーの総数は、メインクエリで使用されるワーカーとサブクエリで使用されるワーカーの数の合計です。
force_parallel_mode セッション

POLARDB オプティマイザーがコスト無視してほとんどのケースで並列クエリを使用するかどうかを指定します。

  • 有効値:ON、OFF
  • 既定値:OFF
重要 これはデバッグパラメーターです。 値を ON に設定した後、POLARDB オプティマイザーはほとんどのケースでクエリを並行して実行できます。 ただし、オプティマイザーが必ずクエリを並列して実行することは保証されません。
Parallel_workers_created セッションとグローバル セッションの開始以降に生成された並列ワーカー数。
Gather_records セッションとグローバル 収集されたレコードの総数。
PQ_refused_over_memory_soft_limit セッションとグローバル メモリ制限のために並列で実行されないクエリの数。
PQ_refused_over_total_workers セッションとグローバル ワーカー総数の制限のために並列で実行されないクエリの数。
Total_used_query_memory グローバル クエリに使用されるメモリ (仮想メモリ) の量。
Total_running_parallel_workers グローバル 実行中の並列ワーカーの数。

並列クエリプラン

次のセクションでは、EXPLAIN 出力に表示される特定の並列クエリプランについて説明します。

  • 並列スキャン

    並列スキャンでは、ワーカーはテーブルのデータを同時スキャンします。 各ワーカーは部分的な結果を生成します。 リーダースレッドは、Gather ノードを使用してすべてのワーカーから結果を収集し、すべての結果をクライアントに返します。

  • 複数のテーブルでの並列結合

    並列クエリを有効にすると、完全なマルチテーブル結合操作が並列処理のためにワーカー間で分割されます。 POLARDB オプティマイザーは、並列スキャンに最適であると見なされるテーブルを 1 つのみ選択します。 他のすべてのテーブルで非並列スキャンが実行されます。 各ワーカーは部分的な結果を生成します。 リーダースレッドは、Gather ノードを使用してすべてのワーカーから結果を収集し、最終結果をクライアントに返します。

  • 並列ソート

    POLARDB オプティマイザーは、並列処理のために ORDER BY 操作をワーカー間で分割します。 各ワーカーは部分的な結果を生成します。 リーダーは、Gather Merge ノードを使用してすべての部分的な結果を収集、マージ、ソートし、最終的なソート結果をクライアントに返します。

  • 並列グループ化

    POLARDB オプティマイザーは、並列処理のために GROUP BY 操作をワーカー間で分割します。 各ワーカーは、データの一部に対する GROUP BY 操作を実行します。 各ワーカーは GROUP BY の部分的な結果を生成します。 リーダースレッドは、Gather ノードを使用してすべてのワーカーから結果を収集します。 クエリプランに基づいて、POLARDB オプティマイザーは、リーダーで GROUP BY 操作の実行も行うかを判断します。 たとえば、ルースインデックススキャンを使用して GROUP BY クエリを実行する場合、リーダーは GROUP BY 操作を実行しません。 ルースインデックススキャンを使用しない場合、リーダーは GROUP BY 操作を実行し、最終結果をクライアントに返します。

  • 並列集計

    集約関数の実行は、並列ワーカー間で分割されます。 POLARDB は、並列集約を二段階でサポートします。 最初に、クエリの並列部分に参加する各ワーカーが集計手順を実行します。 次に、リーダーは Gather または Gather Merge ノードを使用して、すべてのワーカーから結果を収集します。 最後に、リーダーはすべてのワーカーの結果を再集計して、最終結果を生成します。

並列クエリプランの例

次の例では、pq_test テーブルを使用して並列クエリをテストします。

典型的な構造は以下のとおりです。

mysql> SHOW CREATE TABLE pq_test \ G
*************************** 1. row ***************************
       Table: pq_test
Create Table: CREATE TABLE `pq_test` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
  `help_topic_id` INT(10) UNSIGNED NOT NULL,
  `name` CHAR(64) NOT NULL,
  `help_category_id` SMALLINT(5) UNSIGNED NOT NULL,
  `description` TEXT NOT NULL,
  `example` TEXT NOT NULL,
  `url` TEXT NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=21495809 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

以下にテーブルのサイズを示します。

mysql> SHOW TABLE STATUS\G
*************************** 1. row ***************************
           Name: pq_test
         Engine: InnoDB
        Version: 10
     Row_format: Dynamic
           Rows: 20064988
 Avg_row_length: 1898
    Data_length: 38085328896
Max_data_length: 0
   Index_length: 0
      Data_free: 4194304
 Auto_increment: 21495809
    Create_time: 2019-07-30 01:35:27
    Update_time: NULL
     Check_time: NULL
      Collation: utf8_general_ci
       Checksum: NULL
 Create_options:
        Comment:
1 row in set (0.02 sec)

SQL ステートメント :

SELECT COUNT(*) FROM emrusers;
  • EXPLAIN は、並列クエリが使用されていない場合、次の出力を表示します。
    mysql> SET max_parallel_degree=0; EXPLAIN SELECT COUNT(*) FROM pq_test\G
    Query OK, 0 rows affected (0.02 sec)
    *************************** 1. row ***************************
               Id: 1
      Select_type: SIMPLE
            Table: pq_test
      Partitions: NULL
             Type: index
    Possible_keys: NULL
              Key: PRIMARY
          Key_len: 8
              Ref: NULL
             Rows: 20064988
         Filtered: 100.00
            Extra: Using index
    1 row in set, 1 warning (0.03 sec)
  • EXPLAIN は、並列クエリの使用中に次の出力を表示します。
    mysql> EXPLAIN SELECT COUNT(*) FROM pq_test\G
    *************************** 1. row ***************************
               Id: 1
      Select_type: SIMPLE
            Table: <gather2>
       Partitions: NULL
             Type: ALL
    Possible_keys: NULL
              Key: NULL
          Key_len: NULL
              Ref: NULL
             Rows: 20064988
         Filtered: 100.00
            Extra: NULL
    *************************** 2. row ***************************
               Id: 2
      Select_type: SIMPLE
            Table: pq_test
       Partitions: NULL
             Type: index
    Possible_keys: NULL
              Key: PRIMARY
          Key_len: 8
              Ref: NULL
             Rows: 10032494
         Filtered: 100.00
            Extra: Parallel scan (2 workers); Using index
    2 rows in set, 1 warning (0.00 sec)

EXPLAIN 出力のとおり、並列プランには Gather 操作が含まれています。 Gather は、すべてのワーカーによって生成された部分的な結果を収集するために実装されます。 さらに、Extra フィールドの情報は、pq_test テーブルで並列スキャンが実行されることを示します。 このプランでは、2 つのワーカーを使用して同時スキャンを実行することが予測されます。