AnalyticDB for MySQL の SQL 診断機能は、クエリ、ステージ、演算子の各レベルで SQL クエリの統計を収集します。そして、これらの統計を使用して診断と最適化の提案を提供します。このトピックでは、演算子レベルの診断結果を表示および分析する方法について説明します。
診断結果のタイプ
集約演算子の低い集約度
- 問題
集約演算子の集約度は、GROUP BY 操作における入力データ量 (InputDataSize) と出力データ量 (OutputDataSize) の比率です。この比率が小さいほど、集約度が低く、集約の効果が低いことを示します。AnalyticDB for MySQL では、グループ化と集約の操作は、部分集約 (PARTIAL) と最終集約 (FINAL) の 2 つのステップで構成されます。集約演算子に多数のグループが存在する場合、集約度は低くなります。その結果、部分集約ステップではネットワークデータ転送量を削減できず、代わりに多くの計算リソースを消費してしまいます。
- 提案
部分集約ステップをスキップすることを検討してください。ノード間でデータを再分散させた後、単一の最終集約を実行します。詳細については、「グループ化と集約クエリの最適化」をご参照ください。
フィルター条件がプッシュダウンされない
- 問題AnalyticDB for MySQL は、データ保存時にテーブル内のすべてのフィールドに対してインデックスを作成します。これらのインデックスは、クエリ中のデータフィルタリングを高速化します。しかし、AnalyticDB for MySQL は、以下のシナリオではフィルター条件をプッシュダウンしません。
- クエリ文で
no_index_columnsまたはfilter_not_pushdown_columnsヒントが使用されているか、クラスターで adb_config filter_not_pushdown_columns 構成が使用されているため、フィルター条件のプッシュダウン機能が無効になっている場合。 - フィルター条件で
cast演算子などの関数が使用されている場合。 - フィルター条件の関連フィールドにインデックスがない場合。これは、テーブル作成時に
no_indexキーワードが指定されたか、テーブル作成後にDROP INDEXを実行してインデックスが削除された場合に発生する可能性があります。
- クエリ文で
- 提案
- クエリ文のヒントまたはクラスター構成が原因でフィルター条件のプッシュダウン機能が無効になっている場合は、そのヒントまたは構成が使用されている理由を調査し、削除できるかどうかを判断してください。詳細については、「フィルター条件をプッシュダウンしない」をご参照ください。
- 関数が使用されている場合は、データ書き込み時に関数を適用し、クエリから関数を削除することを検討してください。
- 関連フィールドにインデックスがないためにフィルター条件がプッシュダウンされない場合は、インデックスが存在しない理由を調査してください。
Join 操作におけるデータ肥大化
- 問題
Join 操作のデータ肥大化率は、出力行数と入力行数の比率です。入力行数は、左テーブルと右テーブルの行数の合計です。適切な結合条件があれば、通常、出力行数は入力行数よりも少なくなります。出力行数が入力行数よりも多い場合、データ肥大化が発生します。データ肥大化は大量の計算リソースとメモリリソースを消費し、クエリの速度を低下させます。
- 提案
- 両方のテーブルに多数の同一値が存在するなど、データの特性によってデータ肥大化が発生する場合は、テーブルフィルタリングの段階でこれらの値をフィルタリングして Join 操作から除外することを検討してください。
- 結合順序が最適でないためにデータ肥大化が発生する場合は、手動で結合順序を調整してください。詳細については、「結合順序の手動調整」をご参照ください。
Join 操作における右テーブルが大きすぎる
- 問題AnalyticDB for MySQL では、Join 操作の右テーブルは通常ビルダーテーブルであり、メモリ内にハッシュまたはセット構造を構築するために使用されます。右テーブルが大きいと、過剰なメモリリソースを消費し、クラスター全体の安定性に影響を与える可能性があります。右テーブルが大きすぎる原因として、以下の理由が考えられます。
- SQL 文に Left Join が含まれている。Left Join の右テーブルは、実行時にビルダーテーブルでなければなりません。したがって、Left Join の右テーブルが大きい場合、大量のメモリリソースを消費します。
- AnalyticDB for MySQL が左テーブルと右テーブルのデータ量を誤って推定している。これは、期限切れの統計などの要因によって引き起こされる可能性があります。
- 提案
最適化のために、Left Join を Right Join に書き換えることを推奨します。詳細については、「Left Join を Right Join に書き換える」をご参照ください。
Cross Join 操作の存在
- 問題
Cross Join は、結合条件のない Join 操作です。出力行数は、左テーブルと右テーブルの行数の積になります。両方のテーブルが大きい場合、Cross Join は AnalyticDB for MySQL クラスターの安定性に深刻な影響を与える可能性があります。
- 提案
結合条件を追加して Cross Join を解消してください。
スキャン演算子による過剰なフィールド読み取り
- 問題
スキャン演算子は、AnalyticDB for MySQL のストレージレイヤーから詳細データをフィルタリングして読み取ります。SELECT 文に多くのフィールドが含まれている場合、大量の詳細データを読み取る必要があります。これにより、大量のディスク I/O リソースが消費され、AnalyticDB for MySQL クラスター全体の安定性に影響します。
- 提案
SQL 文を最適化して、SELECT 文から不要なフィールドを削除してください。
テーブルスキャンにおけるデータスキュー
- 問題
AnalyticDB for MySQL は分散実行アーキテクチャを使用しています。大きなテーブルの場合、分散キーを指定する必要があります。データ書き込み時に、このキーに基づいてデータが異なるストレージノードに分散されます。分散キーの値が不均一に分散している場合、データもノード間で不均一に保存されます。これにより、データ読み取り時にロングテール効果が発生し、一部のノードが他のノードよりもはるかに長い時間がかかるようになります。この不均衡は、クエリのパフォーマンスに悪影響を及ぼします。
- 提案
適切な分散キーを選択することで、テーブルスキャンにおけるデータスキューを軽減します。最適化方法の詳細については、「ストレージ領域の診断」をご参照ください。
非効率なインデックス
- 問題
AnalyticDB for MySQL がデータフィルタリングにインデックスを使用する場合、フィルタリングされるフィールドの選択性が低いと、インデックスが期待どおりに機能しないことがあります。選択性とは、フィルター演算子の出力データ量と入力データ量の比率です。
- 提案
フィルター条件をプッシュダウンしないことを検討してください。代わりに、計算ノードで直接フィルタリング操作を実行します。詳細については、「フィルター条件をプッシュダウンしない」をご参照ください。