Amazon Aurora MySQL のパラレルクエリの使用 - Amazon Aurora

Amazon Aurora MySQL のパラレルクエリの使用

このトピックでは、Amazon Aurora MySQL 互換エディションのパラレルクエリの最適化機能について説明しています。この機能は、特定のデータ集約型クエリに対して特別な処理パスを使用し、Aurora 共有ストレージアーキテクチャを利用します。パラレルクエリは、数百万行のテーブルと完了までに数分または数時間かかる分析クエリを持つテーブルを持つ Aurora MySQL DB クラスターで最も効果的です。

目次

Aurora MySQL の並列クエリの概要

Aurora MySQL パラレルクエリは、データ集約的なクエリの処理に関連する I/O と計算の一部をパラレル処理する最適化です。パラレル処理される作業には、ストレージから行を取得し、列の値を抽出して、WHERE 句と結合句の条件に一致する行を判別することが含まれます。このデータ集約型の作業は、Aurora 分散ストレージレイヤー内の複数のノードに委譲されます (データベース最適化の用語では、プッシュダウンされます)。並行クエリがないと、各クエリはすべてのスキャンされたデータを Aurora MySQL クラスター (ヘッドノード) 内の単一のノードに持ち込み、そこですべてのクエリ処理を実行します。

ヒント

PostgreSQL データベースエンジンにも「パラレルクエリ」と呼ばれる機能があります。この機能は、Aurora のパラレルクエリとは異なります。

パラレルクエリ特徴を有効にすると、ヒントやテーブル属性などの SQL の変更を必要とせずに、Aurora MySQL エンジンはクエリがいつ利点を得られるかを自動的に判断します。以降のセクションで、パラレルクエリがいつクエリに適用されるかについて説明します。パラレルクエリが最も効果的な場所に適用されていることを確認する方法についても説明します。

注記

パラレルクエリの最適化は、完了までに数分や数時間といった長い時間がかかるクエリの場合に最もメリットがあります。Aurora MySQL は、一般的に安価なクエリのためにはパラレルクエリの最適化を実行しません。また、クエリのキャッシュ、バッファプールのキャッシュ、インデックスの検索などの別の最適化手法を使用したほうが効果的な場合も、通常はパラレルクエリの最適化を行いません。パラレルクエリが適切に使用されていない場合は、「パラレルクエリを使用しているステートメントの確認」を参照してください。

利点

パラレルクエリを使用すると、Aurora MySQL のテーブルに対してデータ集約型の分析クエリを実行できます。多くの場合、従来のようにクエリの処理を分ける場合よりもパフォーマンスが大幅に向上します。

パラレルクエリを使用すると、次のような利点があります。

  • 複数のストレージノード間で物理的な読み取りリクエストをパラレル処理するため、I/O パフォーマンスが向上しました。

  • ネットワークトラフィックの削減。Aurora は、ストレージノードからヘッドノードへデータページ全体を送信せず、その後不要な行および列をフィルタリングで除去します。代わりに、Aurora は、結果セットに必要な列値のみを含むコンパクトなタプルを送信します。

  • 関数の処理、行のフィルタリング、および WHERE 句の列射影をプッシュダウンすることにより、ヘッドノードの CPU 使用率を削減しました。

  • バッファプールのメモリ負荷が低減されました。パラレルクエリによって処理されたページは、バッファプールに追加されません。これにより、データ集約型のスキャンで、頻繁に使用されるデータがバッファプールから削除されることが少なくなります。

  • 既存のデータに対して長時間実行される分析クエリを実用的に実行することで、抽出、変換、ロード (ETL) パイプラインでのデータ重複を潜在的に削減します。

アーキテクチャ

パラレルクエリ機能は、Aurora MySQL の主なアーキテクチャ原則を使用して、ストレージサブシステムからデータベースエンジンをデカップリング、通信プロトコルを効率化してネットワークトラフィックを削減します。Aurora MySQL は、これらの技術を使用して、REDO ログ処理などの書き込み負荷の高いオペレーションを高速化します。パラレルクエリは、同じ原則を読み取り操作に適用します。

注記

Aurora MySQL パラレルクエリのアーキテクチャは、他のデータベースシステムで同様の名前を持つ機能のアーキテクチャとは異なります。Aurora MySQL のパラレルクエリは、対称型マルチプロセッシング (SMP) を利用しないため、データベースサーバーの CPU 容量に依存しません。パラレル処理は、クエリコーディネーターとして機能する Aurora MySQL サーバーとは独立して、ストレージレイヤーで行われます。

デフォルトでは、パラレルクエリを使用しない場合の Aurora のクエリ処理では、Aurora クラスター内の単一のノード (ヘッドノード) に raw データが送られます。Aurora は、その単一ノード上の単一のスレッドで、その後のクエリの処理をすべて実行します。パラレルクエリでは、この I/O 集約型および CPU 集約型の作業の多くは、ストレージレイヤー内のノードに委譲されます。結果セットのコンパクトな行のみがヘッドノードに戻されます (行は既にフィルタリングされ、列の値は既に抽出され、変換されています)。パフォーマンスの利点は、ネットワークトラフィックの削減、ヘッドノードでの CPU 使用率の削減、ストレージノード間の I/O のパラレル化から得られます。パラレル I/O、フィルタリング、および射影の量は、クエリを実行する Aurora クラスター内の DB インスタンスの数に依存しません。

前提条件

パラレルクエリのすべての機能を使用するには、バージョン 2.09 以上を実行している Aurora MySQL DB クラスターが必要です。パラレルクエリを使用したいクラスターが既にある場合は、互換性のあるバージョンにアップグレードしてからパラレルクエリを有効にすることができます。その場合、これらの新しいバージョンでは設定名とデフォルト値が異なるため、「パラレルクエリのアップグレードに関する考慮事項」のアップグレード手順に従ってください。

クラスターの DB インスタンスでは、db.r* インスタンスクラスを使用する必要があります。

クラスターでは、ハッシュ結合の最適化を必ず有効にしてください。この方法については、「パラレルクエリクラスターのハッシュ結合の有効化」を参照してください。

aurora_parallel_queryaurora_disable_hash_join などのパラメータをカスタマイズするには、クラスターで使用するカスタムパラメータグループが必要です。これらのパラメータは、DB パラメータグループを使用して DB インスタンスごとに個別に指定することもできます。ただし、DB クラスターパラメータグループで指定することをお勧めします。これにより、クラスターのすべての DB インスタンスでこれらのパラメータの同じ設定が継承されます。

制限事項

パラレルクエリ機能には、次の制限が適用されます。

  • 並列クエリは Aurora I/O-Optimized DB クラスターのストレージ設定ではサポートされていません。

  • db.t2 または db.t3 インスタンスクラスでは、パラレルクエリは使用できません。この制限は、aurora_pq_force セッション変数を使用してパラレルクエリを行う場合にも適用されます。

  • パラレルクエリは、COMPRESSED または REDUNDANT の行形式を使用するテーブルには適用されません。パラレルクエリを使用するテーブルには、COMPACT または DYNAMIC の行形式を使用してください。

  • Aurora では、コストに基づくアルゴリズムを使用して、それぞれの SQL ステートメントにパラレルクエリを使用するかどうかを判断します。ステートメントで特定の SQL コンストラクトを使用すると、パラレルクエリを防止したり、そのステートメントでパラレルクエリが行われる可能性を低くしたりすることができます。SQL コンストラクトとパラレルクエリの互換性については、「SQL 構造でのパラレルクエリの動作」を参照してください。

  • 各 Aurora DB インスタンスは、一度に特定の数のパラレルクエリセッションのみを実行できます。クエリにサブクエリ、結合、または UNION 演算子などのパラレルクエリを使用する複数の部分がある場合、それらのフェーズは順番に実行されます。このステートメントは、一度に 1 つのパラレルクエリセッションとしてカウントされます。パラレルクエリステータス可変を使用して、アクティブなセッションの数をモニタリングできます。ステータス可変 Aurora_pq_max_concurrent_requests を照会することで、特定の DB インスタンスの同時セッションの制限を確認できます。

  • パラレルクエリは、Aurora がサポートされるすべての AWS リージョンでご利用になれます。ほとんどの AWS リージョンでは、パラレルクエリを使用するために必要な Aurora MySQL の最小バージョンは 2.09 です。

  • パラレルクエリは、データ集約型クエリのパフォーマンスを向上させるように設計されています。軽量のクエリ用向けには設計されていません。

  • SELECT ステートメント、特にデータ量の多いステートメントにはリーダーノードを使用することをお勧めします。

並列クエリの I/O コスト

Aurora MySQL クラスターが並列クエリを使用している場合、VolumeReadIOPS 値が増加することがあります。パラレルクエリでは、バッファプールは使用されません。したがって、クエリは高速ですが、この最適化された処理により、読み取りオペレーションが増加し、関連する料金が増加する可能性があります。

クエリのパラレルクエリ I/O コストは、ストレージレイヤーで計測され、パラレルクエリがオンになっている場合と同じかそれ以上になります。利点は、クエリのパフォーマンスが向上することです。パラレルクエリで I/O コストが高くなる可能性がある理由は 2 つあります。

  • テーブル内のデータの一部がバッファプールにある場合でも、パラレルクエリでは、すべてのデータをストレージレイヤーでスキャンする必要があり、I/O コストが発生します。

  • パラレルクエリを実行しても、バッファプールはウォームアップされません。その結果、同じパラレルクエリを連続して実行すると、完全な I/O コストが発生します。

パラレルクエリクラスターの計画

パラレルクエリが有効な DB クラスターを計画するには、いくつかの選択を行う必要があります。これには、セットアップステップ (完全な Aurora MySQL クラスターの作成または復元) の実行、および DB クラスター全体でパラレルクエリを有効にする範囲の決定が含まれます。

計画の一環として、以下の点を検討してください。

  • MySQL 5.7 と互換性がある Aurora MySQL を使用する場合は、Aurora MySQL 2.09 以上を選択する必要があります。その場合、必ずプロビジョニングされたクラスターを作成します。その上で、aurora_parallel_query パラメータを使用してパラレルクエリを有効にします。

    バージョン 2.09 以上を実行している既存の Aurora MySQL クラスターがある場合は、パラレルクエリを使用するために新しいクラスターを作成する必要はありません。クラスターまたはクラスター内の特定の DB インスタンスを、 aurora_parallel_query パラメータが有効になっているパラメータグループに関連付けることができます。これにより、パラレルクエリで使用する関連データを設定する時間と手間を減らすことができます。

  • アクセス時にパラレルクエリを使用できるように見直す必要がある大きなテーブルについての計画を立てます。いくつかの大きなテーブルでは、パラレルクエリが役立つように新しいものを作成する必要がある場合があります。例えば、全文検索インデックスを削除するなどが必要になる場合があります。詳細については、「パラレルクエリを利用するためのスキーマオブジェクトの作成」を参照してください。

パラレルクエリと Aurora MySQL のバージョンの互換性の確認

パラレルクエリを使用するクラスターと互換性のある Aurora MySQL のバージョンを確認するには、AWS CLI コマンドの describe-db-engine-versions を使用して、SupportsParallelQuery フィールドの値を確認します。次のコード例は、指定された AWS リージョンのパラレルクエリクラスターで使用可能な組み合わせを確認する方法を示しています。--query パラメータのすべての文字列は、必ず 1 行で指定してください。

aws rds describe-db-engine-versions --region us-east-1 --engine aurora-mysql \ --query '*[]|[?SupportsParallelQuery == `true`].[EngineVersion]' --output text

上記のコマンドを実行すると、次のような出力が返されます。この出力は、指定した AWS リージョンで使用可能な Aurora MySQL のバージョンによって異なります。

5.7.mysql_aurora.2.11.1 8.0.mysql_aurora.3.01.0 8.0.mysql_aurora.3.01.1 8.0.mysql_aurora.3.02.0 8.0.mysql_aurora.3.02.1 8.0.mysql_aurora.3.02.2 8.0.mysql_aurora.3.03.0

クラスターでパラレルクエリの使用をスタートしたら、パフォーマンスをモニタリングして、パラレルクエリを使用する上での障害を取り除くことができます。これらの手順については、「パラレルクエリのパフォーマンスチューニング」を参照してください。

パラレルクエリを使用する DB クラスターの作成

パラレルクエリを使用した Aurora MySQL クラスターの作成や、そのクラスターへの新しいインスタンスの追加、あるいは他の管理操作の実行には、他の Aurora MySQL クラスターと同様な、AWS Management Console や AWS CLI のテクニックを使用します。パラレルクエリを処理するための新しいクラスターを作成できます。また、パラレルクエリを使用する DB クラスターは、MySQL と互換性がある Aurora DB クラスターのスナップショットから復元することによって作成することもできます。新しい Aurora MySQL クラスターを作成するプロセスに詳しくない場合は、「Amazon Aurora DB クラスターの作成」の背景情報と前提条件を参照してください。

Aurora MySQL のエンジンのバージョンを選択する場合は、利用可能な最新のバージョンを選択することをお勧めします。現在、Aurora MySQL バージョン 2.09 以降はパラレルクエリをサポートしています。Aurora MySQL 2.09 以上を使用している場合、パラレルクエリの有効と無効を切り替えたり、既存のクラスターでパラレルクエリを使用したりできるため、柔軟性が増します。

新しいクラスターを作成する場合でも、スナップショットから復元する場合でも、同じテクニックを使用して、他の Aurora MySQL クラスターで行う新しい DB インスタンスを追加できます。

コンソールを使用したパラレルクエリクラスターの作成

次のように、コンソールで新しいパラレルクエリクラスターを作成できます。

AWS Management Console コンソールでパラレルクエリクラスターを作成するには
  1. 「AWS Management Console」一般的な Amazon Aurora DB クラスターの作成 の手順に従います。

  2. [Select engine (エンジンの選択)] 画面で、Aurora MySQL を選択します。

    [エンジンバージョン] で、Aurora MySQL 2.09 以降を選択します。これらのバージョンでは、パラレルクエリの使用に関する制限が最も少なくなります。また、これらのバージョンは、いつでもパラレルクエリを有効または無効にできる最も高い柔軟性を備えています。

    クラスターで Aurora MySQL の最新のバージョンを使用するのが現実的でない場合は、[Show versions that support the parallel query feature (パラレルクエリ機能がサポートされているバージョンを表示)] をオンにします。これにより、[Version (バージョン)] メニューがフィルタリングされ、パラレルクエリと互換性がある特定の Aurora MySQL のバージョンのみが表示されます。

  3. [追加設定] で、[DB クラスターパラメータグループ] のために作成したパラメータグループを選択します。Aurora MySQL 2.09 以上では、このようなカスタムパラメータグループを使用する必要があります。DB クラスターパラメータグループで、パラメータ設定の aurora_parallel_query=ONaurora_disable_hash_join=OFF を指定します。これにより、クラスターでパラレルクエリが有効になり、パラレルクエリと組み合わせて使用するハッシュ結合の最適化が有効になります。

新しいクラスターがパラレルクエリを使用できることを確認するには
  1. 上記の方法を使用してクラスターを作成します。

  2. (Aurora MySQL バージョン 2 または 3 の場合) aurora_parallel_query の設定が true であることを確認します。

    mysql> select @@aurora_parallel_query; +-------------------------+ | @@aurora_parallel_query | +-------------------------+ | 1 | +-------------------------+
  3. (Aurora MySQL バージョン 2 の場合) aurora_disable_hash_join 設定が false になっていることを確認します。

    mysql> select @@aurora_disable_hash_join; +----------------------------+ | @@aurora_disable_hash_join | +----------------------------+ | 0 | +----------------------------+
  4. いくつかの大きなテーブルとデータ集約型のクエリについて、クエリの計画を確認して、一部のクエリでパラレルクエリの最適化を使用していることを確認します。これを行うには、「パラレルクエリを使用しているステートメントの確認」の手順に従います。

CLI を使用したパラレルクエリクラスターの作成

次のように、CLI で新しいパラレルクエリクラスターを作成できます。

AWS CLI コンソールでパラレルクエリクラスターを作成するには
  1. (オプション) パラレルクエリを使用するクラスターと互換性のある Aurora MySQL のバージョンを確認します。これを行うには、describe-db-engine-versions コマンドを使用して、SupportsParallelQuery フィールドの値を確認します。例については、「パラレルクエリと Aurora MySQL のバージョンの互換性の確認」を参照してください。

  2. (オプション) aurora_parallel_query=ON 設定と aurora_disable_hash_join=OFF 設定を使用して、カスタム DB クラスターパラメータグループを作成します。以下のようなコマンドを使用します。

    aws rds create-db-cluster-parameter-group --db-parameter-group-family aurora-mysql5.7 --db-cluster-parameter-group-name pq-enabled-57-compatible aws rds modify-db-cluster-parameter-group --db-cluster-parameter-group-name pq-enabled-57-compatible \ --parameters ParameterName=aurora_parallel_query,ParameterValue=ON,ApplyMethod=pending-reboot aws rds modify-db-cluster-parameter-group --db-cluster-parameter-group-name pq-enabled-57-compatible \ --parameters ParameterName=aurora_disable_hash_join,ParameterValue=OFF,ApplyMethod=pending-reboot

    このステップを行う場合は、後続の --db-cluster-parameter-group-name my_cluster_parameter_group ステートメントで create-db-cluster オプションを指定します。パラメータグループの名前は、使用するものに置き換えてください。このステップを省略する場合は、「パラレルクエリのオン/オフを切り替える」の説明に従って、後でパラメータグループを作成してクラスターに関連付けます。

  3. 「AWS CLI」一般的な Amazon Aurora DB クラスターの作成 の手順に従います。

  4. 以下のオプションのセットを指定します。

    • --engine オプションでは、aurora-mysql を使用します。これらの値は、MySQL 5.7 または 8.0 と互換性があるパラレルクエリクラスターを生成します。

    • --db-cluster-parameter-group-name オプションには、作成してパラメータの値に aurora_parallel_query=ON を指定した DB クラスターパラメータグループの名前を指定します。このオプションを省略すると、デフォルトのパラメータグループを使用してクラスターを作成してから、後でこのようなカスタムパラメータグループを使用するように変更できます。

    • --engine-version オプションには、パラレルクエリと互換性がある Aurora MySQL のバージョンを使用します。必要に応じて、「パラレルクエリクラスターの計画」の手順に従ってバージョンの一覧を取得します。少なくとも、バージョン 2.09.0 を使用します。これらのバージョンでは、パラレルクエリが大幅に強化されています。

      次のサンプルはその方法を示しています。$CLUSTER_ID などの環境可変は、それぞれ使用する値に置き換えてください。この例では、--manage-master-user-password オプションも指定して、マスターユーザーパスワードを生成し、Secrets Manager で管理します。詳細については、「Amazon Aurora および AWS Secrets Manager によるパスワード管理」を参照してください。または、--master-password オプションを使用して、自分でパスワードを指定して管理することもできます。

      aws rds create-db-cluster --db-cluster-identifier $CLUSTER_ID \ --engine aurora-mysql --engine-version 5.7.mysql_aurora.2.11.1 \ --master-username $MASTER_USER_ID --manage-master-user-password \ --db-cluster-parameter-group-name $CUSTOM_CLUSTER_PARAM_GROUP aws rds create-db-instance --db-instance-identifier ${INSTANCE_ID}-1 \ --engine same_value_as_in_create_cluster_command \ --db-cluster-identifier $CLUSTER_ID --db-instance-class $INSTANCE_CLASS
  5. 作成または復元したクラスターにパラレルクエリ機能が使用可能であることを確認します。

    aurora_parallel_query 設定が存在することを確認します。この設定の値が 1 の場合は、パラレルクエリを使用する準備ができています。この設定の値が 0 の場合は、パラレルクエリを使用するために 1 に設定します。どちらの場合も、クラスターでパラレルクエリを実行できます。

    mysql> select @@aurora_parallel_query; +------------------------+ | @@aurora_parallel_query| +------------------------+ | 1 | +------------------------+
AWS CLI を使用してスナップショットをパラレルクエリクラスターに復元するには。
  1. パラレルクエリを使用するクラスターと互換性のある Aurora MySQL のバージョンを確認します。これを行うには、describe-db-engine-versions コマンドを使用して、SupportsParallelQuery フィールドの値を確認します。例については、「パラレルクエリと Aurora MySQL のバージョンの互換性の確認」を参照してください。復元したクラスターで使用するバージョンを決定します。MySQL 5.7 互換クラスターの場合、Aurora MySQL 2.09.0 を選択します。

  2. Aurora MySQL 互換クラスターのスナップショットの位置を特定します。

  3. 「AWS CLI」一般的な DB クラスターのスナップショットからの復元 の手順に従います。

    aws rds restore-db-cluster-from-snapshot \ --db-cluster-identifier mynewdbcluster \ --snapshot-identifier mydbclustersnapshot \ --engine aurora-mysql
  4. 作成または復元したクラスターにパラレルクエリ機能が使用可能であることを確認します。CLI を使用したパラレルクエリクラスターの作成 と同じ確認手順を使用してください。

パラレルクエリのオン/オフを切り替える

並列クエリが有効になっている場合、Aurora MySQL はランタイムにクエリごとにそれを使用するかを決定します。結合、ユニオン、サブクエリなどの場合、Aurora MySQL は各クエリブロックに対して実行時にパラレルクエリを使用するかどうかを決定します。詳細については、「パラレルクエリを使用しているステートメントの確認」および「SQL 構造でのパラレルクエリの動作」を参照してください。

aurora_parallel_query オプションを使用して、DB インスタンスのグローバルレベルとセッションレベルの両方でパラレルクエリのオン/オフを動的に切り替えることができます。DB クラスターグループの aurora_parallel_query の設定を変更すると、デフォルトのパラレルクエリの有効と無効を切り替えることができます。

mysql> select @@aurora_parallel_query; +------------------------+ | @@aurora_parallel_query| +------------------------+ | 1 | +------------------------+

aurora_parallel_query パラメータをセッションレベルで切り替えるには、スタンダードの方法を使用してクライアントの設定を変更します。例えば、mysql コマンドラインや JDBC または ODBC アプリケーションで変更できます。このスタンダードの MySQL クライアントのコマンドは set session aurora_parallel_query = {'ON'/'OFF'} です。セッションレベルのパラメータを JDBC 構成またはアプリケーションコード内に追加して、パラレルクエリを動的にオンまたはオフにすることもできます。

aurora_parallel_query パラメータの設定は、特定の DB インスタンスまたはクラスター全体に対して永続的に変更することができます。DB パラメータグループでこのパラメータの値を指定すると、その値はクラスターの特定の DB インスタンスにのみ適用されます。DB クラスターパラメータグループでこのパラメータの値を指定すると、クラスターのすべての DB インスタンスで同じ設定が継承されます。aurora_parallel_query パラメータをクラスターレベルで切り替えるには、「「パラメータグループを使用する」 」で説明されているパラメータグループの使用方法に従います。以下のステップに従ってください。

  1. カスタムクラスターパラメータグループ (推奨) またはカスタム DB パラメータグループを作成します。

  2. このパラメータグループで、parallel_query を必要な値に更新します。

  3. DB クラスターパラメータグループと DB パラメータグループのどちらを作成したかによって、パラレルクエリ機能を使用する Aurora クラスターまたは特定の DB インスタンスにパラメータグループをアタッチします。

    ヒント

    aurora_parallel_query は動的パラメータであるため、この設定を変更した後にクラスターを再起動する必要はありません。ただし、このオプションを切り替える前に並行クエリを使用していた接続は、接続が閉じられるか、インスタンスが再起動されるまで、引き続き実行されます。

パラレルクエリパラメータは、API オペレーションの ModifyDBClusterParameterGroupModifyDBParameterGroup または AWS Management Consoleを使用して変更できます。

パラレルクエリクラスターのハッシュ結合の有効化

パラレルクエリは通常、ハッシュ結合の最適化による利点がある、大量のリソースを使用する種類のクエリに使用されます。そのため、パラレルクエリを使用する予定のクラスターでハッシュ結合を有効にしておくと便利です。ハッシュ結合を効果的に使用する方法については、ハッシュ結合を使用した大規模な Aurora MySQL 結合クエリの最適化 を参照してください。

コンソールを使用したパラレルクエリのオン/オフを切り替える

パラメータグループを使用して、DB インスタンスレベルまたは DB クラスターレベルでパラレルクエリをオン/オフに切り替えることができます。

AWS Management Console で DB クラスターのパラレルクエリをオンまたはオフにする方法
  1. 「パラメータグループを使用する」 」の説明に従って、カスタムパラメータグループを作成します。

  2. aurora_parallel_query1 (オン) または 0 (オフ) に更新します。パラレルクエリ特徴が利用可能なクラスターでは、aurora_parallel_query はデフォルトで無効になっています。

  3. カスタムクラスターパラメータグループを使用する場合は、パラレルクエリ機能を使用する Aurora DB クラスターにアタッチします。カスタム DB パラメータグループを使用する場合は、クラスターの 1 つ以上の DB インスタンスにアタッチします。クラスターパラメータグループを使用することをお勧めします。そうすることにより、クラスターのすべての DB インスタンスでパラレルクエリとそれに関連するハッシュ結合などの機能の設定が同じになります。

CLI を使用したパラレルクエリのオン/オフ切り替え

パラレルクエリのパラメータは、modify-db-cluster-parameter-group または modify-db-parameter-group コマンドを使用して変更することができます。DB クラスターパラメータグループまたは DB パラメータグループのどちらを使用して aurora_parallel_query の値を指定するかに応じて、適切なコマンドを選択してください。

CLI で DB クラスターのパラレルクエリを有効または無効にする方法
  • パラレルクエリパラメータは、modify-db-cluster-parameter-group コマンドを使用して変更します。以下のようなコマンドを使用します。カスタムパラメータグループの名前は、使用する適切なものに置き換えてください。ON オプションの OFF の部分の ParameterValue または --parameters も置き換えてください。

    $ aws rds modify-db-cluster-parameter-group --db-cluster-parameter-group-name cluster_param_group_name \ --parameters ParameterName=aurora_parallel_query,ParameterValue=ON,ApplyMethod=pending-reboot { "DBClusterParameterGroupName": "cluster_param_group_name" } aws rds modify-db-cluster-parameter-group --db-cluster-parameter-group-name cluster_param_group_name \ --parameters ParameterName=aurora_pq,ParameterValue=ON,ApplyMethod=pending-reboot

またセッションレベルでパラレルクエリを有効または無効にすることも可能で、例えば mysql コマンドライン経由や JDBC や ODBC アプリケーション内などで実行できます。これを行うには、スタンダードメソッドを使用してクライアントの構成設定を変更します。例えば、Aurora MySQL では、スタンダード MySQL クライアントに対するコマンドは set session aurora_parallel_query = {'ON'/'OFF'} です。

セッションレベルのパラメータを JDBC 構成またはアプリケーションコード内に追加して、パラレルクエリを動的にオンまたはオフにすることもできます。

パラレルクエリオプティマイザの上書き

aurora_pq_force セッション変数を使用して、パラレルクエリオプティマイザを上書きし、クエリごとにパラレルクエリを行うことができます。これはテスト目的でのみ行うことをお勧めします。次の例では、セッションで aurora_pq_force を使用する方法を示します。

set SESSION aurora_parallel_query = ON; set SESSION aurora_pq_force = ON;

上書きを無効にするには、以下の手順を実行します。

set SESSION aurora_pq_force = OFF;

パラレルクエリのアップグレードに関する考慮事項

パラレルクエリクラスターをアップグレードする際の元のバージョンと移行先のバージョンによっては、パラレルクエリで最適化できるクエリのタイプが強化される場合があります。またパラレルクエリに特別なエンジンモードパラメータを指定する必要がないこともあります。次のセクションでは、パラレルクエリが有効になっているクラスターをアップグレードする際の考慮事項について説明します。

Aurora MySQL バージョン 3 への パラレルクエリクラスターのアップグレード

SQL ステートメント、句、およびデータタイプのいくつかには、Aurora MySQL バージョン 3 からスタートした新しいパラレルクエリサポートまたは改善されたサポートが含まれています。バージョン 3 より前のリリースからアップグレードする場合は、追加のクエリがパラレルクエリ最適化の恩恵を受けることができるかどうかをチェックしてください。これらのパラレルクエリの強化については、列のデータ型パーティションテーブル、および 集計関数、GROUP BY 句、HAVING 句 を参照してください。

Aurora MySQL 2.08 以前からパラレルクエリクラスターをアップグレードする場合は、パラレルクエリを有効にする方法の変更についても確認してください。これを行うには、Aurora MySQL 2.09 以降へのアップグレード を読んでください。

Aurora MySQL バージョン 3 では、ハッシュ結合の最適化はデフォルトで有効になっています。以前のバージョンからの aurora_disable_hash_join 設定オプションは使用されません。

Aurora MySQL 2.09 以降へのアップグレード

Aurora MySQL バージョン 2.09 以上では、パラレルクエリはプロビジョニングされたクラスターで使用できるため、parallelquery エンジンモードパラメータは必要ありません。そのため、これらのバージョンでパラレルクエリを使用するために新しいクラスターを作成したり、既存のスナップショットから復元したりする必要はありません。これらのバージョンでは、「Aurora MySQL DB クラスターのマイナーバージョンまたはパッチレベルのアップグレード」で説明されているアップグレード手順に従ってクラスターをアップグレードできます。古いクラスターでは、パラレルクエリを使用するクラスターかプロビジョニングされたクラスターかにかかわらずアップグレードできます。[Engine version (エンジンバージョン)] メニューの選択肢の数を減らすには、[Show versions that support the parallel query feature (パラレルクエリ機能がサポートされているバージョンを表示)] をオンにしてメニューのエントリをフィルタリングします。その上で、Aurora MySQL 2.09 以上を選択します。

以前のパラレルクエリクラスターを Aurora MySQL 2.09 以上にアップグレードした後、アップグレードしたクラスターでパラレルクエリを有効にします。これらのバージョンではパラレルクエリはデフォルトで無効になっており、有効にする手順も異なります。またハッシュ結合の最適化もデフォルトで無効になっているため、個別に有効にする必要があります。そのため、アップグレード後にはこれらの設定をもう一度有効にしてください。その手順については、「パラレルクエリのオン/オフを切り替える」および「パラレルクエリクラスターのハッシュ結合の有効化」を参照してください。

特に、aurora_pq_supportedaurora_pq ではなく、aurora_parallel_query=ONaurora_disable_hash_join=OFF の設定パラメータを使用してパラレルクエリを有効にするようにしてください。aurora_pq_supported パラメータと aurora_pq パラメータは、Aurora MySQL の新しいバージョンでは非推奨になっています。

アップグレードしたクラスターでは、EngineMode 属性の値は provisioned ではなく、parallelquery になります。指定したエンジンバージョンでパラレルクエリが使用できるかどうかを確認するには、SupportsParallelQuery コマンドの describe-db-engine-versions の出力の AWS CLI フィールドの値を確認します。Aurora MySQL の以前のバージョンでは、parallelquery の一覧に SupportedEngineModes があることを確認していました。

Aurora MySQL バージョン 2.09 以上にアップグレードすると、以下の機能を利用できるようになります。これらの機能は、Aurora MySQL の古いバージョンが実行されているパラレルクエリを使用するクラスターでは使用できません。

パラレルクエリのパフォーマンスチューニング

パラレルクエリを使用してワークロードのパフォーマンスを管理するには、この最適化が最も役立つクエリに対してパラレルクエリが使用されていることを確認します。

そのためには、以下を実行できます。

パラレルクエリを利用するためのスキーマオブジェクトの作成

パラレルクエリで使用するテーブルを作成または変更するには、「前提条件」および「制限事項」で説明されている要件を理解しておく必要があります。

パラレルクエリでは、テーブルに ROW_FORMAT=Compact または ROW_FORMAT=Dynamic の設定が使用されている必要があるため、Aurora の設定で INNODB_FILE_FORMAT 設定オプションへの変更を確認してください。SHOW TABLE STATUS ステートメントを発行して、データベース内のすべてのテーブルの行形式を確認します。

より多くのテーブルを処理するためにパラレルクエリをオンにするようにスキーマを変更する前に、必ずテストを行ってください。テストでは、パラレルクエリによってそれらのテーブルのパフォーマンスが実際に向上するかどうかを確認する必要があります。また、パラレルクエリのスキーマ要件が目標に適合していることを確認してください。

例えば、ROW_FORMAT=Compressed から ROW_FORMAT=Compact または ROW_FORMAT=Dynamic に切り替える前には、元のテーブルと新しいテーブルでワークロードのパフォーマンスをテストします。また、データ量の増加などの潜在的な影響も考慮してください。

パラレルクエリを使用しているステートメントの確認

一般的な操作では、パラレルクエリを利用するために特別なアクションを実行する必要はありません。クエリがパラレルクエリの必須要件を満たした後、クエリオプティマイザは、特定のクエリごとにパラレルクエリを使用するかどうかを自動的に決定します。

開発環境やテスト環境で実験を行うと、テーブルの行数や全体のデータ量が少ないためにパラレルクエリが使用されないことがあります。特に実験を実行するために最近作成したテーブルの場合、テーブルのデータも完全にバッファプールにある可能性があります。

クラスターのパフォーマンスをモニタリングまたは調整する場合は、パラレルクエリが適切な状況で使用されているかどうかを確認する必要があります。この機能を利用するには、データベースのスキーマ、設定、SQL クエリ、またはクラスタートポロジとアプリケーションの接続設定を調整する必要があります。

クエリでパラレルクエリが使用されているかどうかを確認するには、EXPLAIN ステートメントを実行してクエリプラン (explain プラン) を確認します。パラレルクエリの EXPLAIN 出力に SQL ステートメント、句および表現がどのように影響するかの例は、「SQL 構造でのパラレルクエリの動作」を参照してください。

次の例は、従来のクエリプランとパラレルクエリプランの違いを示しています。この explain プランは、TPC-H ベンチマークのクエリ 3 のものです。このセクションのサンプルクエリの多くは、TPC-H データセットのテーブルを使用しています。テーブル定義、クエリ、サンプルデータを生成する dbgen プログラムは、TPC-H のウェブサイトから入手できます。

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

デフォルトでは、クエリには以下のようなプランがあります。クエリプランでハッシュ結合が使用されていない場合は、初期に最適化がオンになっていることを確認してください。

+----+-------------+----------+------------+------+---------------+------+---------+------+----------+----------+----------------------------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+----------+------------+------+---------------+------+---------+------+----------+----------+----------------------------------------------------+ | 1 | SIMPLE | customer | NULL | ALL | NULL | NULL | NULL | NULL | 1480234 | 10.00 | Using where; Using temporary; Using filesort | | 1 | SIMPLE | orders | NULL | ALL | NULL | NULL | NULL | NULL | 14875240 | 3.33 | Using where; Using join buffer (Block Nested Loop) | | 1 | SIMPLE | lineitem | NULL | ALL | NULL | NULL | NULL | NULL | 59270573 | 3.33 | Using where; Using join buffer (Block Nested Loop) | +----+-------------+----------+------------+------+---------------+------+---------+------+----------+----------+----------------------------------------------------+

Aurora MySQL バージョン 3 の場合、次のステートメントを発行すると、セッションレベルでハッシュ結合を有効にできます。

SET optimizer_switch='block_nested_loop=on';

Aurora MySQL バージョン 2.09 以降では、aurora_disable_hash_join DB パラメーターまたは DB クラスターパラメータを 0 (オフ) に設定します。aurora_disable_hash_join をオフにすると、optimizer_switch の値が hash_join=on に設定されます。

ハッシュ結合を有効にした後、EXPLAIN ステートメントをもう一度実行してみてください。ハッシュ結合を効果的に使用する方法については、ハッシュ結合を使用した大規模な Aurora MySQL 結合クエリの最適化 を参照してください。

ハッシュ結合がオンになっているがパラレルクエリがオフになっている場合、クエリには次のようなプランが含まれる可能性があります。これは、ハッシュ結合を使用しますが、パラレルクエリは使用しません。

+----+-------------+----------+...+-----------+-----------------------------------------------------------------+ | id | select_type | table |...| rows | Extra | +----+-------------+----------+...+-----------+-----------------------------------------------------------------+ | 1 | SIMPLE | customer |...| 5798330 | Using where; Using index; Using temporary; Using filesort | | 1 | SIMPLE | orders |...| 154545408 | Using where; Using join buffer (Hash Join Outer table orders) | | 1 | SIMPLE | lineitem |...| 606119300 | Using where; Using join buffer (Hash Join Outer table lineitem) | +----+-------------+----------+...+-----------+-----------------------------------------------------------------+

パラレルクエリが有効になると、EXPLAIN 出力の Extra カラムに表示されるように、このクエリプランの 2 つのステップでパラレルクエリの最適化が使用できます。これらのステップに対する I/O 集約型および CPU 集約型の処理は、ストレージレイヤーにプッシュダウンされます。

+----+...+--------------------------------------------------------------------------------------------------------------------------------+ | id |...| Extra | +----+...+--------------------------------------------------------------------------------------------------------------------------------+ | 1 |...| Using where; Using index; Using temporary; Using filesort | | 1 |...| Using where; Using join buffer (Hash Join Outer table orders); Using parallel query (4 columns, 1 filters, 1 exprs; 0 extra) | | 1 |...| Using where; Using join buffer (Hash Join Outer table lineitem); Using parallel query (4 columns, 1 filters, 1 exprs; 0 extra) | +----+...+--------------------------------------------------------------------------------------------------------------------------------+

パラレルクエリの出力およびパラレルクエリが適用できる SQL ステートメントの部分の EXPLAIN 出力を解釈する方法については、「SQL 構造でのパラレルクエリの動作」を参照してください。

次の出力例は、コールドバッファプールを持つ db.r4.2xlarge インスタンスで前のクエリを実行した結果を示しています。パラレルクエリを使用すると、クエリが大幅に高速化されます。

注記

タイミングは多くの環境要因に依存するため、結果が異なる場合があります。自分の環境、ワークロードなどで結果を確認するには、常に独自のパフォーマンステストを実施してください。

-- Without parallel query +------------+-------------+-------------+----------------+ | l_orderkey | revenue | o_orderdate | o_shippriority | +------------+-------------+-------------+----------------+ | 92511430 | 514726.4896 | 1995-03-06 | 0 | . . | 28840519 | 454748.2485 | 1995-03-08 | 0 | +------------+-------------+-------------+----------------+ 10 rows in set (24 min 49.99 sec)
-- With parallel query +------------+-------------+-------------+----------------+ | l_orderkey | revenue | o_orderdate | o_shippriority | +------------+-------------+-------------+----------------+ | 92511430 | 514726.4896 | 1995-03-06 | 0 | . . | 28840519 | 454748.2485 | 1995-03-08 | 0 | +------------+-------------+-------------+----------------+ 10 rows in set (1 min 49.91 sec)

このセクション全体のサンプルクエリの多くは、この TPC-H データセットのテーブル、特に 2000 万行と以下の定義を持つ PART テーブルを使用しています。

+---------------+---------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------------+---------------+------+-----+---------+-------+ | p_partkey | int(11) | NO | PRI | NULL | | | p_name | varchar(55) | NO | | NULL | | | p_mfgr | char(25) | NO | | NULL | | | p_brand | char(10) | NO | | NULL | | | p_type | varchar(25) | NO | | NULL | | | p_size | int(11) | NO | | NULL | | | p_container | char(10) | NO | | NULL | | | p_retailprice | decimal(15,2) | NO | | NULL | | | p_comment | varchar(23) | NO | | NULL | | +---------------+---------------+------+-----+---------+-------+

ワークロードを試して、個々の SQL ステートメントがパラレルクエリを利用できるかどうかを理解してください。次に、以下のモニタリング方法を使用して、実際のワークロードでパラレルクエリが使用される頻度を時間をかけて確認します。実際のワークロードでは、同時実行制限などの追加の要素が適用されます。

パラレルクエリのモニタリング

Aurora MySQL クラスターがパラレルクエリを使用している場合、VolumeReadIOPS 値が増加することがあります。パラレルクエリでは、バッファプールは使用されません。したがって、クエリは高速ですが、この最適化された処理により、読み取り操作とそれに関連する料金が増加する可能性があります。

Amazon RDS コンソールでのメトリクスの表示 で説明されている Amazon CloudWatch メトリクスに加えて、Aurora は他のグローバルなステータス可変を提供します。これらのグローバルステータス可変を使用して、パラレルクエリの実行のモニタリングに役立てることができます。これらの変数からは、オプティマイザが特定の状況でパラレルクエリを使用したり、使用しなかったりする理由についてのインサイトを得ることができます。これらの可変にアクセスするには、SHOW GLOBAL STATUS コマンドを使用します。これらの可変は次のとおりです。

パラレルクエリセッションは、データベースによって実行されるクエリと必ずしも 1 対 1 のマッピングにはなっていません。例えば、クエリプランにパラレルクエリを使用する 2 つのステップがあるとします。この場合、クエリには 2 つのパラレルセッションが含まれ、試行された要求と成功したリクエストのカウンターは 2 つずつ増分されます。

EXPLAIN ステートメントを発行してパラレルクエリを試してみると、実際にはクエリが実行されていなくても「選択されていません」と指定されたカウンターの増加が見込まれます。本稼働環境でパラレルクエリを処理する場合、「選択されていない」カウンターが予想どおりに高速に増加しているかどうかを確認できます。その段階で、目的のクエリでパラレルクエリが実行されるように調整できます。これを行うには、パラレルクエリが有効になっている クラスターの設定、クエリの組み合わせ、DB インスタンスなどを変更します。

これらのカウンターは、DB インスタンスレベルで追跡されます。別のエンドポイントに接続すると、各 DB インスタンスが独自のパラレルクエリセットを実行するため、別のメトリクスが表示されることがあります。リーダーエンドポイントがセッションごとに異なる DB インスタンスに接続すると、別のメトリクスが表示されることもあります。

名前 説明

Aurora_pq_bytes_returned

パラレルクエリ中にヘッドノードに送信されたタプルデータ構造のバイト数。Aurora_pq_pages_pushed_down と比較するために 16,384 で割ります。

Aurora_pq_max_concurrent_requests

この Aurora DB インスタンスで同時に実行できるパラレルクエリセッションの最大数。これは、AWS の DB インスタンスクラスによって異なる固定の数です。

Aurora_pq_pages_pushed_down

パラレルクエリがヘッドノードへのネットワーク送信を回避したデータページ数 (それぞれ 16 KiB の固定サイズ)。

Aurora_pq_request_attempted

リクエストされたパラレルクエリセッションの数。この値は、サブクエリや結合などの SQL 構成に応じて、クエリごとに複数のセッションを表す場合があります。

Aurora_pq_request_executed

パラレルクエリセッションの数は正常に実行されます。

Aurora_pq_request_failed

クライアントにエラーを戻したパラレルクエリセッションの数。場合によっては、例えば、ストレージレイヤーの問題のために、パラレルクエリのリクエストが失敗することがあります。このような場合、失敗したクエリ部分は、非パラレルクエリメカニズムを使用して再試行されます。再試行されたクエリも失敗すると、エラーがクライアントに返され、このカウンターが増分されます。

Aurora_pq_request_in_progress

現在進行中のパラレルクエリセッションの数。この数は、Aurora DB クラスター全体ではなく、接続している特定の Aurora DB インスタンスのものが適用されます。DB インスタンスが同時実行の制限に近いかどうかを調べるには、この値を Aurora_pq_max_concurrent_requests と比較します。

Aurora_pq_request_not_chosen

クエリを満たすためにパラレルクエリが選択されなかった回数。この値は、他のいくつかのより細かいカウンターの合計です。EXPLAIN ステートメントでは、クエリが実際に実行されていない場合でもこのカウンターは増加します。

Aurora_pq_request_not_chosen_below_min_rows

テーブル内の行数のためにパラレルクエリが選択されなかった回数。EXPLAIN ステートメントでは、クエリが実際に実行されていない場合でもこのカウンターは増加します。

Aurora_pq_request_not_chosen_column_bit

射影された列の中にサポートされていないデータ型があるために、パラレルクエリ以外の処理方法が使用されるパラレルクエリのリクエスト数。

Aurora_pq_request_not_chosen_column_geometry

テーブルに GEOMETRY データ型の列があるために、パラレルクエリ以外の処理方法が使用されるパラレルクエリのリクエスト数。この制限を解除する Aurora MySQL のバージョンについては、Aurora MySQL バージョン 3 への パラレルクエリクラスターのアップグレード を参照してください。

Aurora_pq_request_not_chosen_column_lob

LOB データタイプ、または宣言された長さのため外部に保存された VARCHAR カラムをテーブルが持っていることが原因で、非パラレルクエリの処理パスを使用したパラレルクエリのリクエスト数。この制限を解除する Aurora MySQL のバージョンについては、Aurora MySQL バージョン 3 への パラレルクエリクラスターのアップグレード を参照してください。

Aurora_pq_request_not_chosen_column_virtual

テーブルに仮想列があるために、パラレルクエリ以外の処理方法が使用されるパラレルクエリのリクエスト数。

Aurora_pq_request_not_chosen_custom_charset

テーブルにカスタム文字セットの列があるために、パラレルクエリ以外の処理方法が使用されるパラレルクエリのリクエスト数。

Aurora_pq_request_not_chosen_fast_ddl

テーブルが高速 DDL の ALTER ステートメントによって変更中であるために、パラレルクエリ以外の処理方法が使用されるパラレルクエリのリクエスト数。

Aurora_pq_request_not_chosen_few_pages_outside_buffer_pool

パラレルクエリを価値のあるものにするためのバッファされていないテーブルデータが十分ないため、テーブルデータの 95 パーセント未満がバッファプールにあったにもかかわらず、パラレルクエリの回数は選択されませんでした。

Aurora_pq_request_not_chosen_full_text_index

テーブルに全文インデックスがあるために、パラレルクエリ以外の処理方法が使用されるパラレルクエリのリクエスト数。

Aurora_pq_request_not_chosen_high_buffer_pool_pct

テーブルデータの高パーセンテージ (現在は 95 パーセント以上) が既にバッファプールに入っていたため、パラレルクエリが選択されなかった回数。このような場合、オプティマイザは、バッファプールからのデータの読取りがより効率的であると判断します。EXPLAIN ステートメントでは、クエリが実際に実行されていない場合でもこのカウンターは増加します。

Aurora_pq_request_not_chosen_index_hint

クエリにインデックスヒントが含まれているために、パラレルクエリ以外の処理方法が使用されるパラレルクエリのリクエスト数。

Aurora_pq_request_not_chosen_innodb_table_format

テーブルが、サポートされていない InnoDB の行形式を使用しているために、パラレルクエリ以外の処理方法が適用されるパラレルクエリのリクエスト数。Aurora のパラレルクエリは、COMPACTREDUNDANT,および DYNAMIC の行形式にのみ適用されます。

Aurora_pq_request_not_chosen_long_trx

長時間実行トランザクション内でクエリがスタートされているために、非パラレルクエリ処理パスを使用したパラレルクエリリクエストの数。EXPLAIN ステートメントでは、クエリが実際に実行されていない場合でもこのカウンターは増加します。

Aurora_pq_request_not_chosen_no_where_clause

クエリに WHERE 句がないために、パラレルクエリ以外の処理方法が使用されるパラレルクエリのリクエスト数。

Aurora_pq_request_not_chosen_range_scan

インデックスの範囲スキャンを使用しているために、パラレルクエリ以外の処理方法が使用されるパラレルクエリのリクエスト数。

Aurora_pq_request_not_chosen_row_length_too_long

すべての列の合計長が長すぎるために、パラレルクエリ以外の処理方法が使用されるパラレルクエリのリクエスト数。

Aurora_pq_request_not_chosen_small_table

行数および平均行長によって決定される、テーブルの全体的なサイズのためにパラレルクエリが選択されなかった回数。EXPLAIN ステートメントでは、クエリが実際に実行されていない場合でもこのカウンターは増加します。

Aurora_pq_request_not_chosen_temporary_table

クエリでサポートされていない MyISAM また memory テーブルタイプを使用しているテンポラリテーブルを参照しているために、パラレルクエリ以外の処理方法が使用されるパラレルクエリのリクエスト数。

Aurora_pq_request_not_chosen_tx_isolation

クエリでサポートされていないトランザクション分離レベルを使用しているために、パラレルクエリ以外の処理方法が使用されるパラレルクエリのリクエスト数。リーダー DB インスタンスでは、パラレルクエリは REPEATABLE READ および READ COMMITTED 分離レベルにのみ適用されます。

Aurora_pq_request_not_chosen_update_delete_stmts

クエリが UPDATE または DELETE ステートメントの一部であるために、パラレルクエリ以外の処理方法が使用されるパラレルクエリのリクエスト数。

Aurora_pq_request_not_chosen_unsupported_access

WHERE 句がパラレルクエリの基準を満たしていないために、非パラレルクエリ処理パスを使用するパラレルクエリリクエストの数。この結果は、クエリがデータ集約型スキャンを必要としない場合、またはクエリが DELETE または UPDATE ステートメントである場合に発生します。

Aurora_pq_request_not_chosen_unsupported_storage_type

Aurora MySQL DB クラスターがサポートされている Aurora クラスターストレージ設定を使用していないために非並列クエリ処理パスを使用する並列クエリリクエストの数。このパラメータは、Aurora MySQL バージョン 3.04 以降で使用できます。詳細については、「制限事項」を参照してください。

Aurora_pq_request_throttled

特定の Aurora DB インスタンスで既に実行されている同時パラレルクエリの最大数のために、パラレルクエリが選択されなかった回数。

SQL 構造でのパラレルクエリの動作

このセクションでは、特定の SQL ステートメントでパラレルクエリが使用される理由と使用されない理由について詳しく説明します。また、Aurora MySQL の機能とパラレルクエリのインタラクションについても説明します。これらの内容は、パラレルクエリを使用するクラスターのパフォーマンスの問題を診断したり、特定のワークロードにパラレルクエリがどのように適用されるかを理解したりするために役立ちます。

パラレルクエリを使用するかどうかの決定は、ステートメントが実行される時点で発生する多くの要因に依存します。したがって、パラレルクエリは、特定の条件の下で常に使用される、特定の条件の下では決して使用されない、または特定の条件の下でのみ使用される特定のクエリに対して使用される可能性があります。

ヒント

以下の例を HTML で表示している場合は、記載されている各コードの右上隅にあるコピーウィジェットを使用して SQL コードをコピーして使用することができます。このコピーウィジェットを使用すると、mysql> プロンプトとそれに続く -> の行の周りの余分な文字がコピーされません。

EXPLAIN ステートメント

このセクションの例で示すように、EXPLAIN ステートメントは、クエリの各ステージが現在パラレルクエリに適しているかどうかを示します。また、クエリのどの側面をストレージレイヤーにプッシュダウンできるかを示します。以下に、クエリプランで最も重要な点を示します。

  • NULL 列の key 以外の値は、インデックスのルックアップを使用してクエリを効率的に実行できることを示しています。またパラレルクエリは効率的には実行できません。

  • rows 列の値が小さい場合 (値が百万単位に達しない場合) は、クエリでアクセスしているデータがパラレルクエリが役立つほどの量ではないことを示しています。そのため、パラレルクエリが使用されることはあまりありません。

  • Extra 列には、パラレルクエリを使用することが予想されるかどうかを示します。この出力は、次の例のようになります。

    Using parallel query (A columns, B filters, C exprs; D extra)

    columns の数は、クエリブロックで参照される列の数を表します。

    filters の数は、列の値と定数の簡単な比較を表す WHERE 述語の数を表します。比較には、等価、不等値、または範囲を使用することができます。Aurora は、これらの種類の述語を最も効果的にパラレル化できます。

    exprs の数は、関数呼び出し、演算子、またはパラレル化できる他の表現の数を表しますが、フィルター条件ほど効果的ではありません。

    extra の数は、プッシュダウンできず、ヘッドノードによって実行される表現の数を表します。

例えば、次の EXPLAIN 出力を考えてみます。

mysql> explain select p_name, p_mfgr from part -> where p_brand is not null -> and upper(p_type) is not null -> and round(p_retailprice) is not null; +----+-------------+-------+...+----------+----------------------------------------------------------------------------+ | id | select_type | table |...| rows | Extra | +----+-------------+-------+...+----------+----------------------------------------------------------------------------+ | 1 | SIMPLE | part |...| 20427936 | Using where; Using parallel query (5 columns, 1 filters, 2 exprs; 0 extra) | +----+-------------+-------+...+----------+----------------------------------------------------------------------------+

Extra 列の情報は、各行から 5 つの列が抽出され、クエリ条件を評価し結果セットを構成することを示しています。1 つの WHERE 述語にはフィルター、つまり WHERE 句で直接テストされた列が含まれます。2 つの WHERE 句では、この場合は関数呼び出しを含む、より複雑な表現を評価する必要があります。0 extra フィールドは、WHERE 句のすべての操作がパラレルクエリ処理の一部としてストレージレイヤーにプッシュダウンされることを確認します。

パラレルクエリが選択されていない場合は、通常、EXPLAIN 出力の他の列から理由を推測できます。例えば、rows 値が小さすぎたり、possible_keys 列が、データ集約型スキャンではなくインデックスルックアップを使用できることを示します。次の例は、オプティマイズがクエリでスキャンする行の数が少ないとみなすクエリを示しています。これは、主キーの文字数に基づいて判断されます。この場合、パラレルクエリは不要です。

mysql> explain select count(*) from part where p_partkey between 1 and 100; +----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+ | 1 | SIMPLE | part | range | PRIMARY | PRIMARY | 4 | NULL | 99 | Using where; Using index | +----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+

パラレルクエリを使用するかどうかを示す出力には、EXPLAIN ステートメントが実行された時点で利用可能なすべての要素が考慮されます。その間に状況が変わった場合、オプティマイザはクエリが実際に実行されたときに別の選択肢を作る場合もあります。例えば、EXPLAIN は、ステートメントがパラレルクエリを使用すると報告する場合があります。しかし、クエリが実際に後で実行される場合は、条件に基づいてパラレルクエリを使用しないことがあります。このような条件には、同時に実行されている他の複数のパラレルクエリが含まれます。また、テーブルから削除される行、作成される新しいインデックス、実行中のトランザクションに時間がかかりすぎていることなども含まれます。

WHERE 句

クエリがパラレルクエリの最適化を使用するには、WHERE 句を含める必要があります

パラレルクエリの最適化は、WHERE 句で使用される多くの種類の表現を高速化します。

  • 列の値と定数の簡単な比較は、フィルターとして知られています。これらの比較は、ストレージレイヤーへのプッシュダウンを最大限に活用します。クエリのフィルター表現の数は、EXPLAIN 出力でレポートされます。

  • WHERE 句にある他の種類の表現も、可能であれば、ストレージレイヤーにプッシュダウンされます。クエリ内のそのような表現の数は、EXPLAIN 出力でレポートされます。これらの表現は、関数呼び出し、LIKE 演算子、CASE 表現などです。

  • 特定の関数と演算子は、現在、パラレルクエリによってプッシュダウンされていません。クエリ内のそのような表現の数は、extra 出力の EXPLAIN カウンターとしてレポートされます。残りのクエリは引き続きパラレルクエリを使用できます。

  • 選択リスト内の表現はプッシュダウンされませんが、そのような関数を含むクエリは、パラレルクエリの中間結果のネットワークトラフィックが減少しても有益です。例えば、選択リスト内の集計関数を呼び出すクエリでは、集計関数がプッシュダウンされていなくても、パラレルクエリを使用できます。

例えば、次のクエリはテーブル全体のスキャンを実行し、P_BRAND 列のすべての値を処理します。ただし、クエリには WHERE 句が含まれていないため、パラレルクエリは使用されません。

mysql> explain select count(*), p_brand from part group by p_brand; +----+-------------+-------+------+---------------+------+---------+------+----------+---------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+----------+---------------------------------+ | 1 | SIMPLE | part | ALL | NULL | NULL | NULL | NULL | 20427936 | Using temporary; Using filesort | +----+-------------+-------+------+---------------+------+---------+------+----------+---------------------------------+

対照的に、次のクエリには、結果をフィルタリングする WHERE 述語が含まれているため、パラレルクエリを適用できます。

mysql> explain select count(*), p_brand from part where p_name is not null -> and p_mfgr in ('Manufacturer#1', 'Manufacturer#3') and p_retailprice > 1000 -> group by p_brand; +----+...+----------+-------------------------------------------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+----------+-------------------------------------------------------------------------------------------------------------+ | 1 |...| 20427936 | Using where; Using temporary; Using filesort; Using parallel query (5 columns, 1 filters, 2 exprs; 0 extra) | +----+...+----------+-------------------------------------------------------------------------------------------------------------+

オプティマイザが、クエリブロックの戻される行数が少ないと見積もった場合、そのクエリブロックに対してパラレルクエリは使用されません。次の例は、プライマリキー列のより大きい演算子が数百万行にも適用され、パラレルクエリが使用される場合を示しています。その反対に数の少ないテストでは、ほんの数行にしか適用されず、パラレルクエリは使用されません。

mysql> explain select count(*) from part where p_partkey > 10; +----+...+----------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+----------+----------------------------------------------------------------------------+ | 1 |...| 20427936 | Using where; Using parallel query (1 columns, 1 filters, 0 exprs; 0 extra) | +----+...+----------+----------------------------------------------------------------------------+ mysql> explain select count(*) from part where p_partkey < 10; +----+...+------+--------------------------+ | id |...| rows | Extra | +----+...+------+--------------------------+ | 1 |...| 9 | Using where; Using index | +----+...+------+--------------------------+

データ定義言語 (DDL)

Aurora MySQL バージョン 2 では、パラレルクエリは、高速データ定義言語 (DDL) オペレーションが保留されていないテーブルでのみ利用可能です。Aurora MySQL バージョン 3 では、インスタント DDL オペレーションと同時にテーブルに対してパラレルクエリを使用できます。

Aurora MySQL バージョン 3 のインスタント DDL では、Aurora MySQL バージョン 2 の高速 DDL 機能が置き換えられます。DDL ステートメントの詳細については、インスタント DDL (Aurora MySQL バージョン 3) を参照してください。

列のデータ型

Aurora MySQL バージョン 3 では、パラレルクエリはデータタイプ TEXTBLOBJSON、および GEOMETRY のカラムを含むテーブルで使用できます。また、宣言された長さの最大数が 768 バイト以上の VARCHAR 、および CHAR のカラムでも使用することが可能です。クエリがそのようなラージオブジェクトタイプを含む列を参照している場合、それを取得するための追加作業によってクエリ処理にオーバーヘッドが発生します。その場合、それらの列への参照をクエリが省略できるかチェックしてください。そうでない場合は、ベンチマークを実行し、パラレルクエリをオンまたはオフにしてた状態でこのようなクエリが高速であるかどうかを確認します。

Aurora MySQL バージョン 2 では、ラージオブジェクトタイプに対してパラレルクエリは次の制限があります。

  • TEXTBLOBJSONGEOMETRY データ型は、並列クエリではサポートされていません。これらの型の列を参照するクエリは、並列クエリを使用できません。

  • 可変長の列 (VARCHAR および CHAR) は、最大 768 バイトの宣言された最大長までの並列クエリと互換性があります。上記より長い最大長で宣言された型の列を参照するクエリは、並列クエリを使用できません。マルチバイト文字セットを使用する列の場合、バイト制限には文字セット内の最大バイト数が考慮されます。例えば、最大文字長が 4 バイトの文字セット utf8mb4 の場合、VARCHAR(192) 列はパラレルクエリと互換性がありますが、VARCHAR(193) 列は互換性はありません。

パーティションテーブル

Aurora MySQL バージョン 3 では、パーティショニングされたテーブルをパラレルクエリで使用できます。パーティショニングテーブルは内部的に複数の小さなテーブルとして表されるため、非パーティションテーブルに対してパラレルクエリを使用するクエリでは、同一のパーティショニングテーブルに対してパラレルクエリを使用しない場合があります。Aurora MySQL は、テーブル全体のサイズを評価するのではなく、各パーティションがパラレルクエリ最適化の対象となるのに十分な大きさがあるかどうかを検討します。パーティショニングテーブルのクエリがパラレルクエリを使用しない場合、Aurora_pq_request_not_chosen_small_table ステータス 可変がインクリメントされているかどうかをチェックしてください。

例えば、PARTITION BY HASH (column) PARTITIONS 2 でパーティショニングされている一つのテーブルと、PARTITION BY HASH (column) PARTITIONS 10 でパーティション分散されている別のテーブルについて考えてみます。2 つのパーティションがあるテーブルでは、パーティションは 10 個のパーティションを持つテーブルの 5 倍になります。したがって、パラレルクエリは、パーティションがより少ないテーブルに対するクエリに使用される可能性が高くなります。次の例では、テーブル PART_BIG_PARTITIONS には 2 つのパーティションがあり、PART_SMALL_PARTITIONS には 10 個のパーティションがあります。同一データでは、大きなパーティションがより少ないテーブルに対してパラレルクエリは使用される可能性が高くなります。

mysql> explain select count(*), p_brand from part_big_partitions where p_name is not null -> and p_mfgr in ('Manufacturer#1', 'Manufacturer#3') and p_retailprice > 1000 group by p_brand; +----+-------------+---------------------+------------+-------------------------------------------------------------------------------------------------------------------+ | id | select_type | table | partitions | Extra | +----+-------------+---------------------+------------+-------------------------------------------------------------------------------------------------------------------+ | 1 | SIMPLE | part_big_partitions | p0,p1 | Using where; Using temporary; Using parallel query (4 columns, 1 filters, 1 exprs; 0 extra; 1 group-bys, 1 aggrs) | +----+-------------+---------------------+------------+-------------------------------------------------------------------------------------------------------------------+ mysql> explain select count(*), p_brand from part_small_partitions where p_name is not null -> and p_mfgr in ('Manufacturer#1', 'Manufacturer#3') and p_retailprice > 1000 group by p_brand; +----+-------------+-----------------------+-------------------------------+------------------------------+ | id | select_type | table | partitions | Extra | +----+-------------+-----------------------+-------------------------------+------------------------------+ | 1 | SIMPLE | part_small_partitions | p0,p1,p2,p3,p4,p5,p6,p7,p8,p9 | Using where; Using temporary | +----+-------------+-----------------------+-------------------------------+------------------------------+

集計関数、GROUP BY 句、HAVING 句

集計関数を含むクエリは、大規模なテーブル内の多数の行をスキャンするため、パラレルクエリに適しています。

Aurora MySQL 3 では、パラレルクエリは選択リストと HAVING 句内の集計関数呼び出しを最適化できます。

Aurora MySQL 3 より前では、選択リストまたは HAVING 句の集計関数呼び出しはストレージレイヤーにプッシュダウンされませんでした。ただし、パラレルクエリは、集計関数を使用してこのようなクエリのパフォーマンスを向上させることができます。これは、初期にストレージレイヤーでパラレルに raw データページから列値を抽出することによって行われます。次に、それらの値をデータページ全体ではなくコンパクトなタプル形式でヘッドノードに戻します。今回も、クエリにはパラレルクエリを有効にするための少なくとも 1 つの WHERE 述語が必要です。

次の簡単な例は、パラレルクエリの利点を受ける集約クエリの種類を示しています。これは、中間結果をコンパクト形式でヘッドノードに戻し、一致しない行を中間結果から除外するか、またはその両方を行うことによって行います。

mysql> explain select sql_no_cache count(distinct p_brand) from part where p_mfgr = 'Manufacturer#5'; +----+...+----------------------------------------------------------------------------+ | id |...| Extra | +----+...+----------------------------------------------------------------------------+ | 1 |...| Using where; Using parallel query (2 columns, 1 filters, 0 exprs; 0 extra) | +----+...+----------------------------------------------------------------------------+ mysql> explain select sql_no_cache p_mfgr from part where p_retailprice > 1000 group by p_mfgr having count(*) > 100; +----+...+-------------------------------------------------------------------------------------------------------------+ | id |...| Extra | +----+...+-------------------------------------------------------------------------------------------------------------+ | 1 |...| Using where; Using temporary; Using filesort; Using parallel query (3 columns, 0 filters, 1 exprs; 0 extra) | +----+...+-------------------------------------------------------------------------------------------------------------+

WHERE 句での関数呼び出し

Aurora は、WHERE 句のほとんどの組み込み関数への呼び出しにパラレルクエリの最適化を適用できます。これらの関数呼び出しをパラレル化すると、いくつかの CPU 作業がヘッドノードからオフロードされます。最も早いクエリステージで述語関数を並行して評価することで、Aurora は後のステージで送信および処理されるデータ量を最小限に抑えることができます。

現在、パラレル化は選択リストの関数呼び出しには適用されません。これらの関数は、同じ関数呼び出しが WHERE 句に現れても、ヘッドノードによって評価されます。関連する列からの元の値は、ストレージノードからヘッドノードに送信されたタプルに含まれます。ヘッドノードは、UPPERCONCATENATE などの変換を行って、結果セットの最終的な値を生成します。

次の例では、LOWER 句にあるため、パラレルクエリは WHERE の呼び出しをパラレル化します。SUBSTRUPPER の呼び出しは選択したリストにあるため、パラレルクエリには影響されません。

mysql> explain select sql_no_cache distinct substr(upper(p_name),1,5) from part -> where lower(p_name) like '%cornflower%' or lower(p_name) like '%goldenrod%'; +----+...+---------------------------------------------------------------------------------------------+ | id |...| Extra | +----+...+---------------------------------------------------------------------------------------------+ | 1 |...| Using where; Using temporary; Using parallel query (2 columns, 0 filters, 1 exprs; 0 extra) | +----+...+---------------------------------------------------------------------------------------------+

CASE 表現や LIKE 演算子など、他の表現にも同じ考慮事項が適用されます。次の例では、パラレルクエリは、CASE 句の LIKE 表現と WHERE演算子を評価します。

mysql> explain select p_mfgr, p_retailprice from part -> where p_retailprice > case p_mfgr -> when 'Manufacturer#1' then 1000 -> when 'Manufacturer#2' then 1200 -> else 950 -> end -> and p_name like '%vanilla%' -> group by p_retailprice; +----+...+-------------------------------------------------------------------------------------------------------------+ | id |...| Extra | +----+...+-------------------------------------------------------------------------------------------------------------+ | 1 |...| Using where; Using temporary; Using filesort; Using parallel query (4 columns, 0 filters, 2 exprs; 0 extra) | +----+...+-------------------------------------------------------------------------------------------------------------+

LIMIT 句

現在のところ、LIMIT 句を含むクエリブロックでは、パラレルクエリは使用されません。GROUP by、ORDER BY、または結合を使用して、以前のクエリフェーズでもパラレルクエリを使用することができます。

比較演算子

オプティマイザは、比較演算子を評価するためにスキャンする行数を推定し、その推定値に基づいてパラレルクエリを使用するかどうかを決定します。

次の初期の例は、プライマリキー列との等価比較をパラレルクエリなしで効率的に実行できることを示しています。次の 2 番目の例では、インデックス作成されていない列に対する同様の比較では数百万行のスキャンが必要なため、パラレルクエリのメリットが得られます。

mysql> explain select * from part where p_partkey = 10; +----+...+------+-------+ | id |...| rows | Extra | +----+...+------+-------+ | 1 |...| 1 | NULL | +----+...+------+-------+ mysql> explain select * from part where p_type = 'LARGE BRUSHED BRASS'; +----+...+----------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+----------+----------------------------------------------------------------------------+ | 1 |...| 20427936 | Using where; Using parallel query (9 columns, 1 filters, 0 exprs; 0 extra) | +----+...+----------+----------------------------------------------------------------------------+

等しくないテストや、より小さい、より大きい、等しい、または BETWEEN などの範囲比較にも同じ考慮事項が適用されます。オプティマイザは、スキャンする行数を推定し、I/O 全体の量に基づいてパラレルクエリが有効かどうかを判断します。

Joins

大きなテーブルを使用した結合クエリには、通常、パラレルクエリの最適化のメリットを受けるデータ集約型操作が含まれます。現在、複数のテーブル (つまり、結合述語自体) 間の列値の比較パラレルパラレル化されません。ただし、パラレルクエリは、ハッシュ結合中に Bloom フィルターを構築するなど、他の結合フェーズの内部処理の一部をプッシュダウンできます。パラレルクエリは、WHERE 句がなくても結合クエリに適用できます。したがって、結合クエリは、パラレルクエリを使用するために WHERE 句が必要であるという規則に対する例外です。

結合処理の各フェーズが評価され、パラレルクエリに適格であるかどうかがチェックされます。複数のフェーズでパラレルクエリを使用できる場合は、これらのフェーズが順番に実行されます。したがって、各結合クエリは、同時実行制限に関して単一のパラレルクエリセッションとしてカウントされます。

例えば、結合クエリが結合テーブルの 1 つから行をフィルタリングする WHERE 述語を含む場合、そのフィルタリングオプションはパラレルクエリを使用できます。別の例として、結合クエリがハッシュ結合メカニズムを使用するとします。例えば、大きなテーブルを小さなテーブルに結合する場合などです。この場合、Bloom フィルターデータ構造を生成するためのテーブルスキャンは、パラレルクエリを使用することができます。

注記

パラレルクエリは通常、ハッシュ結合の最適化による利点がある、大量のリソースを使用する種類のクエリに使用されます。ハッシュ結合の最適化を有効にする方法は、Aurora MySQL のバージョンによって異なります。各バージョンの詳細については、パラレルクエリクラスターのハッシュ結合の有効化 を参照してください。ハッシュ結合を効果的に使用する方法については、ハッシュ結合を使用した大規模な Aurora MySQL 結合クエリの最適化 を参照してください。

mysql> explain select count(*) from orders join customer where o_custkey = c_custkey; +----+...+----------+-------+---------------+-------------+...+-----------+-----------------------------------------------------------------------------------------------------------------+ | id |...| table | type | possible_keys | key |...| rows | Extra | +----+...+----------+-------+---------------+-------------+...+-----------+-----------------------------------------------------------------------------------------------------------------+ | 1 |...| customer | index | PRIMARY | c_nationkey |...| 15051972 | Using index | | 1 |...| orders | ALL | o_custkey | NULL |...| 154545408 | Using join buffer (Hash Join Outer table orders); Using parallel query (1 columns, 0 filters, 1 exprs; 0 extra) | +----+...+----------+-------+---------------+-------------+...+-----------+-----------------------------------------------------------------------------------------------------------------+

ネストされたループメカニズムを使用する結合クエリの場合、最も外側のネストされたループブロックはパラレルクエリを使用する場合があります。パラレルクエリの使用は、WHERE 句に追加のフィルター条件が存在するなど、通常と同じ要素に依存します。

mysql> -- Nested loop join with extra filter conditions can use parallel query. mysql> explain select count(*) from part, partsupp where p_partkey != ps_partkey and p_name is not null and ps_availqty > 0; +----+-------------+----------+...+----------+----------------------------------------------------------------------------+ | id | select_type | table |...| rows | Extra | +----+-------------+----------+...+----------+----------------------------------------------------------------------------+ | 1 | SIMPLE | part |...| 20427936 | Using where; Using parallel query (2 columns, 1 filters, 0 exprs; 0 extra) | | 1 | SIMPLE | partsupp |...| 78164450 | Using where; Using join buffer (Block Nested Loop) | +----+-------------+----------+...+----------+----------------------------------------------------------------------------+

サブクエリ

外部クエリブロックと内部サブクエリブロックでは、そのそれぞれでパラレルクエリを使用するかどうかが決定されます。各ブロックで使用するかどうかは、テーブルの通常の特徴や WHERE 句などに基づきます。例えば、次のクエリでは、外部ブロックではなくサブクエリブロックに対してパラレルクエリが使用されます。

mysql> explain select count(*) from part where --> p_partkey < (select max(p_partkey) from part where p_name like '%vanilla%'); +----+-------------+...+----------+----------------------------------------------------------------------------+ | id | select_type |...| rows | Extra | +----+-------------+...+----------+----------------------------------------------------------------------------+ | 1 | PRIMARY |...| NULL | Impossible WHERE noticed after reading const tables | | 2 | SUBQUERY |...| 20427936 | Using where; Using parallel query (2 columns, 0 filters, 1 exprs; 0 extra) | +----+-------------+...+----------+----------------------------------------------------------------------------+

現在、相関サブクエリはパラレルクエリ最適化を使用できません。

UNION

UNION クエリの各クエリブロックは、WHERE の各部分に対して、テーブルの通常の特性、または UNION 句などに基づいてパラレルクエリを使用するかどうかを指定できます。

mysql> explain select p_partkey from part where p_name like '%choco_ate%' -> union select p_partkey from part where p_name like '%vanil_a%'; +----+----------------+...+----------+----------------------------------------------------------------------------+ | id | select_type |...| rows | Extra | +----+----------------+...+----------+----------------------------------------------------------------------------+ | 1 | PRIMARY |...| 20427936 | Using where; Using parallel query (2 columns, 0 filters, 1 exprs; 0 extra) | | 2 | UNION |...| 20427936 | Using where; Using parallel query (2 columns, 0 filters, 1 exprs; 0 extra) | | NULL | UNION RESULT | <union1,2> |...| NULL | Using temporary | +----+--------------+...+----------+----------------------------------------------------------------------------+
注記

クエリ内の各 UNION 句は順番に実行されます。クエリにすべてがパラレルクエリを使用する複数のステージが含まれていても、常に 1 つのパラレルクエリしか実行されません。したがって、複雑な複数ステージのクエリであっても、同時並行クエリの制限として 1 つだけカウントされます。

ビュー

オプティマイザは、基になるテーブルを使用して、より長いクエリとしてビューを使用するクエリをすべて書き換えます。したがって、パラレルクエリは、テーブル参照がビューでも実テーブルであっても同じように機能します。クエリに対してパラレルクエリを使用するかどうか、およびプッシュダウンする部分については、最終的に書き直されたクエリに同じ考慮事項が適用されます。

例えば、次のクエリプランは、通常はパラレルクエリを使用しないビューの定義を示しています。追加の WHERE 句でビューがクエリされると、Aurora MySQL はパラレルクエリを使用します。

mysql> create view part_view as select * from part; mysql> explain select count(*) from part_view where p_partkey is not null; +----+...+----------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+----------+----------------------------------------------------------------------------+ | 1 |...| 20427936 | Using where; Using parallel query (1 columns, 0 filters, 0 exprs; 1 extra) | +----+...+----------+----------------------------------------------------------------------------+

データ操作言語 (DML) ステートメント

INSERT 部分がパラレルクエリの他の条件を満たしている場合、SELECT ステートメントは処理の SELECT フェーズに対してパラレルクエリを使用できます。

mysql> create table part_subset like part; mysql> explain insert into part_subset select * from part where p_mfgr = 'Manufacturer#1'; +----+...+----------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+----------+----------------------------------------------------------------------------+ | 1 |...| 20427936 | Using where; Using parallel query (9 columns, 1 filters, 0 exprs; 0 extra) | +----+...+----------+----------------------------------------------------------------------------+
注記

通常、INSERT ステートメントの後に、新しく挿入された行のデータがバッファプールにあります。したがって、多数の行を挿入した直後に、テーブルがパラレルクエリに適格でない可能性があります。後で、通常の操作中にバッファプールからデータが除去された後に、テーブルに対するクエリがパラレルクエリを再び使用し始める可能性があります。

ステートメントの CREATE TABLE AS SELECT 部分がパラレルクエリに適格であっても、SELECT ステートメントはパラレルクエリを使用しません。このステートメントの DDL 側面は、パラレルクエリ処理と互換性がありません。対照的に、INSERT ... SELECT ステートメントでは、SELECT 部分はパラレルクエリを使用できます。

パラレルクエリは、DELETE 句のテーブルおよび述語のサイズに関係なく、UPDATEステートメントまたは WHERE ステートメントには使用されません。

mysql> explain delete from part where p_name is not null; +----+-------------+...+----------+-------------+ | id | select_type |...| rows | Extra | +----+-------------+...+----------+-------------+ | 1 | SIMPLE |...| 20427936 | Using where | +----+-------------+...+----------+-------------+

トランザクションとロック

すべての分離レベルは、Aurora プライマリインスタンスで使用できます。

Aurora リーダー DB インスタンスでは、パラレルクエリは REPEATABLE READ の分離レベルの下で実行されるステートメントに適用されます。Aurora MySQL バージョン 2.09 以降では、リーダー DB インスタンスに対して READ COMMITTED 分離レベルも使用されます。REPEATABLE READ は、Aurora リーダー DB インスタンスのデフォルトの分離レベルです。リーダー DB インスタンスで READ COMMITTED 分離レベルを使用するには、セッションレベルで aurora_read_replica_read_committed 設定オプションを設定する必要があります。READ COMMITTEDリーダーインスタンスの分離レベルは SQL のスタンダード動作に準拠しています。ただし、この分離は、クエリがライターインスタンスで READ COMMITTED 分離レベルを使用する場合よりも、リーダーインスタンスでは厳密ではありません。

Aurora の分離レベル、特にライターインスタンスとリーダーインスタンス間での READ COMMITTED の違いについては、Aurora MySQL の分離レベル を参照してください。

大きなトランザクションが終了した後、テーブルの統計情報は古くなっている可能性があります。このような古くなった統計では、Aurora が正確に行数を見積もるには、ANALYZE TABLE ステートメントが必要になることがあります。大規模な DML ステートメントでは、テーブルデータのかなりの部分がバッファプールに持ち込まれる可能性があります。このデータをバッファプールに入れると、データがプールから削除されるまで、パラレルクエリの選択頻度が低くなります。

セッションが長時間実行トランザクション (デフォルトでは 10 分) 内にある場合、そのセッション内の以降のクエリはパラレルクエリを使用しません。1 つの長期実行クエリ中にもタイムアウトが発生する可能性があります。このタイプのタイムアウトは、パラレルクエリ処理がスタートされるまでの最大間隔 (現在は 10 分) より長くクエリが実行された場合に発生する可能性があります。

autocommit=1 セッションに mysql を設定して、偶発的に長時間実行トランザクションがスタートされる機会を減らすことができます。テーブルに対する SELECT ステートメントでさえ、読み取りビューを作成してトランザクションをスタートします。読み取りビューは、トランザクションがコミットされるまで続くクエリ用の一貫したデータセットです。このようなアプリケーションは autocommit 設定をオフにして実行する可能性があるため、Aurora で JDBC または ODBC アプリケーションを使用する場合にもこの制限に注意してください。

次の例は、autocommit 設定をオフにして、テーブルに対してクエリを実行すると、暗黙的にトランザクションをスタートする読み取りビューが作成される方法を示しています。すぐ後で実行されるクエリは引き続きパラレルクエリを使用できます。ただし、数分の休止後は、クエリはもはやパラレルクエリの対象となりません。COMMIT または ROLLBACK を使用してトランザクションを終了すると、パラレルクエリの適格性が復元されます。

mysql> set autocommit=0; mysql> explain select sql_no_cache count(*) from part where p_retailprice > 10.0; +----+...+---------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+---------+----------------------------------------------------------------------------+ | 1 |...| 2976129 | Using where; Using parallel query (1 columns, 1 filters, 0 exprs; 0 extra) | +----+...+---------+----------------------------------------------------------------------------+ mysql> select sleep(720); explain select sql_no_cache count(*) from part where p_retailprice > 10.0; +------------+ | sleep(720) | +------------+ | 0 | +------------+ 1 row in set (12 min 0.00 sec) +----+...+---------+-------------+ | id |...| rows | Extra | +----+...+---------+-------------+ | 1 |...| 2976129 | Using where | +----+...+---------+-------------+ mysql> commit; mysql> explain select sql_no_cache count(*) from part where p_retailprice > 10.0; +----+...+---------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+---------+----------------------------------------------------------------------------+ | 1 |...| 2976129 | Using where; Using parallel query (1 columns, 1 filters, 0 exprs; 0 extra) | +----+...+---------+----------------------------------------------------------------------------+

クエリが長時間実行トランザクションのためにパラレルクエリに適格でなかった回数を確認するには、ステータス可変 Aurora_pq_request_not_chosen_long_trx を確認します。

mysql> show global status like '%pq%trx%'; +---------------------------------------+-------+ | Variable_name | Value | +---------------------------------------+-------+ | Aurora_pq_request_not_chosen_long_trx | 4 | +-------------------------------+-------+

SELECT 構文や SELECT FOR UPDATE 構文などのロックを取得するすべての SELECT LOCK IN SHARE MODE ステートメントでは、パラレルクエリを使用できません。

パラレルクエリは、LOCK TABLES ステートメントによってロックされているテーブルに対して機能します。

mysql> explain select o_orderpriority, o_shippriority from orders where o_clerk = 'Clerk#000095055'; +----+...+-----------+----------------------------------------------------------------------------+ | id |...| rows | Extra | +----+...+-----------+----------------------------------------------------------------------------+ | 1 |...| 154545408 | Using where; Using parallel query (3 columns, 1 filters, 0 exprs; 0 extra) | +----+...+-----------+----------------------------------------------------------------------------+ mysql> explain select o_orderpriority, o_shippriority from orders where o_clerk = 'Clerk#000095055' for update; +----+...+-----------+-------------+ | id |...| rows | Extra | +----+...+-----------+-------------+ | 1 |...| 154545408 | Using where | +----+...+-----------+-------------+

B ツリーインデックス

ANALYZE TABLE ステートメントによって収集される統計は、各列のデータの特性に基づいて、パラレルクエリまたはインデックスのルックアップをいつ使用するかをオプティマイザが決定するのに役立ちます。テーブル内のデータを大幅に変更する DML 操作の後で ANALYZE TABLE を実行することにより、統計情報を最新の状態に保ちます。

インデックスのルックアップがデータ集約型スキャンなしで効率的にクエリを実行できる場合は、Aurora は インデックスのルックアップを使用する可能性があります。そうすることにより、パラレルクエリ処理のオーバーヘッドが回避されます。また、どの Aurora DB クラスターでも同時に実行できるパラレルクエリの数には同時実行制限があります。テーブルのインデックス付けにベストプラクティスを使用して、最も頻繁で最も並行性の高いクエリがインデックスのルックアップを使用するようにしてください。

全文検索 (FTS) インデックス

現在のところ、全文検索インデックスを含むテーブルでは、クエリで全文検索インデックスのある列を参照しているか MATCH 演算子を使用しているかどうかにかかわらず、パラレルクエリは使用されません。

仮想列

現在のところ、仮想列を含むテーブルでは、クエリで仮想列を参照しているかどうかにかかわらず、パラレルクエリは使用されません。

組み込みキャッシュメカニズム

Aurora には、組み込みキャッシュメカニズム、つまりバッファプールとクエリキャッシュが組み込まれています。Aurora オプティマイザは、どのクエリが特定のクエリに対して最も効果的かに応じて、これらのキャッシュメカニズムとパラレルクエリを選択します。

パラレルクエリが行をフィルタリングし、列の値を変換して抽出すると、データはデータページではなくタプルとしてヘッドノードに返されます。したがって、パラレルクエリを実行しても、バッファプールにはページが追加されず、既にバッファプールにあるページは削除されます。

Aurora は、バッファプール内に存在するテーブルデータのページ数と、その番号が表すテーブルデータの割合を検証します。Aurora はその情報を使用して、パラレルクエリを使用する方が効率的かどうかを判断します (また、バッファプール内のデータをバイパスします)。または、Aurora はバッファプールにキャッシュされたデータを使用する非パラレルクエリ処理パスを使用することがあります。キャッシュされるページと、データ集約型のクエリがキャッシュおよび削除に与える影響は、バッファプールに関連する構成設定によって異なります。したがって、バッファプール内の常に変化するデータに依存するため、特定のクエリでパラレルクエリが使用されているかどうかを予測することは困難です。

また、Aurora はパラレルクエリに同時実行制限を課します。すべてのクエリがパラレルクエリを使用するわけではないので、複数のクエリによって同時にアクセスされるテーブルは、通常、バッファプール内のデータのかなりの部分を占めます。したがって、Aurora はパラレルクエリに対してこれらのテーブルを選択しないことがよくあります。

同じテーブルで非パラレルクエリのシーケンスを実行すると、データがバッファプールにないため、初期のクエリが遅くなる可能性があります。これでバッファプールが「ウォームアップ」状態になるため、2 番目以降のクエリは非常に高速になります。パラレルクエリは、通常、テーブルに対する初期のクエリからの一貫したパフォーマンスを示します。パフォーマンステストを実行するときは、コールドバッファプールとウォームバッファプールの両方を使用して、非パラレルクエリを評価します。場合によっては、ウォームバッファプールを使用した結果は、パラレルクエリ時間とよく比較できます。その場合、そのテーブルに対するクエリの頻度などの要因を考慮してください。また、そのテーブルのデータをバッファプールに保持するメリットがあるかどうかも考慮してください。

クエリキャッシュは、同じクエリが送信されたときに基になるテーブルのデータに変更がない場合に、クエリがもう一度実行されることを防ぎます。パラレルクエリ機能によって最適化されたクエリは、クエリキャッシュに入り、効果的に再度実行することができます。

注記

パフォーマンスの比較を行うとき、クエリキャッシュは意図的に低いタイミング数を生成する可能性があります。したがって、ベンチマークのような状況では、sql_no_cache ヒントを使用できます。このヒントは、以前に同じクエリが実行された場合でも、クエリキャッシュから結果が提供されるのを防ぎます。ヒントは、クエリの SELECT ステートメントの直後に表示されます。このトピック内のパラレルクエリ例の多くにはこのヒントが含まれているので、パラレルクエリで有効化されているクエリとそうでないクエリのバージョン間で、クエリ時間を比較できます。

パラレルクエリの本稼働使用に移行するときは、出典からこのヒントを削除するようにしてください。

オプティマイザヒント

オプティマイザを制御するもう 1 つの方法は、オプティマイザヒントを使用することです。オプティマイザヒントは個々のステートメント内で指定できます。例えば、ステートメント内の 1 つのテーブルの最適化を有効にして、別のテーブルの最適化を無効にすることができます。これらのヒントの詳細については、MySQL リファレンスマニュアルの「オプティマイザヒント」を参照してください。

Aurora MySQL クエリで SQL ヒントを使用して、パフォーマンスを微調整できます。ヒントを使用して、重要なクエリの実行計画が予測不可能な条件のために変更されないようにすることもできます。

SQL ヒント機能を拡張して、クエリプランのオプティマイザの選択を制御できるようにしました。これらのヒントは、パラレルクエリ最適化を使用するクエリに適用されます。詳細については、「Aurora MySQL のヒント」を参照してください。

MyISAM テンポラリテーブル

パラレルクエリの最適化は、InnoDB テーブルにのみ適用されます。Aurora MySQL はテンポラリテーブルの背後で MyISAM を使用するため、テンポラリテーブルを含む内部クエリフェーズではパラレルクエリは使用されません。これらのクエリフェーズは、Using temporary 出力に EXPLAIN によって示されています。