このトピックでは、EXPLAINおよびEXPLAIN ANALYZEコマンドを実行して実行計画を分析する方法について説明します。

前提条件

クラスターのバージョンはV3.1.3以降です。

AnalyticDB For MySQLクラスターのバージョンを表示する方法については、「AnalyticDB for MySQLクラスターのバージョンを表示する方法」をご参照ください。 バージョンをアップグレードするには、してください。

EXPLAIN

EXPLAINコマンドを実行して、SQLクエリステートメントの実行予定パスを評価できます。 この評価は参考用であり、実際の実行結果と同じ重みは与えられていません。

  • 構文
    EXPLAIN (フォーマットテキスト) <SELECT文>;
    SQLクエリステートメントが複雑でない場合は、(format text) フィールドをEXPLAINコマンドに追加して、返された結果のツリー階層の読みやすさを高めることができます。
  • EXPLAIN (フォーマットテキスト)
          SELECTカウント (*)
          FROM
          国家、地域、顧客
          WHERE
          c_nationkey = n_nationkey
          AND n_regionkey = r_regionkey
          AND r_name = 'ASIA';
    次の応答が返されます。
    出力 [カウント (*)]
    │ 出力: [count:bigint]
    │ 見積もり: {rows: 1 (8B)}
    │ count(*) := count
    └ ─ 集約 (ファイナル)
       │ 出力: [count:bigint]
       │ 見積もり: {rows: 1 (8B)}
       │ count := count('count_1 ')
       └ ─ LocalExchange [シングル] ()
          │ 出力: [count_0_1:bigint]
          │ 見積もり: {rows: 1 (8B)}
          └ ─ RemoteExchange [ギャザー]
             │ 出力: [count_0_2:bigint]
             │ 見積もり: {rows: 1 (8B)}
             └ ─ 集約 (PARTIAL)
                │ 出力: [count_0_4:bigint]
                │ 見積もり: {rows: 1 (8B)}
                │ count_4 := count(*)
                └ ─ InnerJoin[('c_nationkey' = 'n_nationkey')][$hashvalue, $hashvalue_0_6]
                   │ 出力: []
                   │ 見積もり: {行: 302035 (4.61MB)}
                   │ 配布: REPLICATED
                   ├─ プロジェクト []
                   出力: [c_nationkey:integer, $hashvalue:bigint]
                   │ │ 見積もり: {rows: 1500000 (5.72MB)}
                   │ │ $hashvalue := 'combine_hash'(BIGINT '0', COALESCE('$operato r$ hash_code'('c_nationkey'), 0))
                   │ õ ─ RuntimeFilter
                   出力: [c_nationkey:integer]
                   │ │ 見積もり: {rows: 1500000 (5.72MB)}
                   │ ├─ TableScan[adb:AdbTableHandle{schema=tpch, tableName=customer, partitionColumnHandles=[c_custkey]}]
                   出力: [c_nationkey:integer]
                   │ │ 見積もり: {rows: 1500000 (5.72MB)}
                   │ │ c_nationkey := AdbColumnHandle{columnName=c_nationkey, type=4, isIndexed=true}
                   │ õ ─ RuntimeCollect
                   出力: [n_nationkey: 整数]
                   │ │ 見積もり: {rows: 5 (60B)}
                   │ └ ─ LocalExchange[ROUND_ROBIN] ()
                   出力: [n_nationkey: 整数]
                   │ │ 見積もり: {rows: 5 (60B)}
                   │ õ ─ RuntimeScan
                   │ 出力: [n_nationkey: 整数]
                   │ 見積もり: {rows: 5 (60B)}
                   └ ─ LocalExchange[HASH][$hashvalue_0_6] ("n_nationkey")
                      │ 出力: [n_nationkey:integer, $hashvalue_0_6:bigint]
                      │ 見積もり: {rows: 5 (60B)}
                      └ ─ プロジェクト []
                         │ 出力: [n_nationkey:integer, $hashvalue_0_10:bigint]
                         │ 見積もり: {rows: 5 (60B)}
                         │ $hashvalue_10 := 'combine_hash'(BIGINT '0', COALESCE('$operato r$ hash_code'('n_nationkey'), 0))
                         └ ─ RemoteExchange[REPLICATE]
                            │ 出力: [n_nationkey: 整数]
                            │ 見積もり: {rows: 5 (60B)}
                            └ ─ InnerJoin[('n_regionkey' = 'r_regionkey')][$hashvalue_0_7, $hashvalue_0_8]
                               │ 出力: [n_nationkey: 整数]
                               │ 見積もり: {rows: 5 (60B)}
                               │ 配布: REPLICATED
                               ├─ プロジェクト []
                               出力: [n_nationkey:integer, n_regionkey:integer, $hashvalue_0_7:bigint]
                               │ │ 見積もり: {rows: 25 (200B)}
                               │ │ $hashvalue_7 := 'combine_hash'(BIGINT '0', COALESCE('$operato r$ hash_code'('n_regionkey'), 0))
                               │ õ ─ RuntimeFilter
                               出力: [n_nationkey:integer, n_regionkey:integer]
                               │ │ 見積もり: {rows: 25 (200B)}
                               │ ├─ TableScan[adb:AdbTableHandle{schema=tpch, tableName=nation, partitionColumnHandles=[]}]
                               出力: [n_nationkey:integer, n_regionkey:integer]
                               │ │ 見積もり: {rows: 25 (200B)}
                               │ │ n_nationkey := AdbColumnHandle{columnName=n_nationkey, type=4, isIndexed=true}
                               │ │ n_regionkey := AdbColumnHandle{columnName=n_regionkey, type=4, isIndexed=true}
                               │ õ ─ RuntimeCollect
                               出力: [r_regionkey:integer]
                               │ │ 見積もり: {rows: 1 (4B)}
                               │ └ ─ LocalExchange[ROUND_ROBIN] ()
                               出力: [r_regionkey:integer]
                               │ │ 見積もり: {rows: 1 (4B)}
                               │ õ ─ RuntimeScan
                               │ 出力: [r_regionkey:integer]
                               │ 見積もり: {rows: 1 (4B)}
                               └ ─ LocalExchange[HASH][$hashvalue_0_8] ("r_regionkey")
                                  │ 出力: [r_regionkey:integer, $hashvalue_0_8:bigint]
                                  │ 見積もり: {rows: 1 (4B)}
                                  └ ─ ScanProject[table = adb:AdbTableHandle{schema=tpch、tableName=region、partitionColumnHandles=[]}]
                                         出力: [r_regionkey:integer, $hashvalue_0_9:bigint]
                                         見積もり: {rows: 1 (4B)}/{rows: 1 (B)}
                                         $hashvalue_9 := 'combine_hash'(BIGINT '0', COALESCE('$operato r$ hash_code'('r_regionkey'), 0))
                                         r_regionkey := AdbColumnHandle{columnName=r_regionkey, type=4, isIndexed=true}
    次の表に、上記の結果の主なパラメーターを示します。
    パラメーター 説明
    出力: [symbol:type] 各演算子の出力列とデータ型。
    見積もり: {rows: % s (% sB)} 各演算子の推定行数とデータ量。 データは、オプティマイザの結合順序付けおよびデータシャフリング技術を決定するために使用することができる。

EXPLAIN ANALYZE

EXPLAIN ANALYZEコマンドを実行して、分散実行プランと、実行時間、メモリ使用量、入出力データ量など、クエリの実際の実行コストを照会できます。

  • 構文
    EXPLAIN ANALYZE <SELECTステートメント>;
  • 分析の説明
    SELECTカウント (*)
          FROM
          国家、地域、顧客
          WHERE
          c_nationkey = n_nationkey
          AND n_regionkey = r_regionkey
          AND r_name = 'ASIA';
    次の応答が返されます。
    フラグメント1 [シングル]
        出力: 1行 (9B) 、PeakMemory: 178KB、WallTime: 1.00ns、入力: 32行 (288B); タスクごと: avg.: 32.00 std.de v.: 0.00
        出力レイアウト: [count]
        Output partitioning: SINGLE []
        集計 (最終)
        │ 出力: [count:bigint]
        │ 見積もり: {rows: 1 (8B)}
        │ 出力: 2行 (18B) 、ピークメモリ: 24B (0.00%) 、WallTime: 70.39us (0.03%)
        │ count := count('count_1 ')
        └ ─ LocalExchange [シングル] ()
           │ 出力: [count1:bigint]
           │ 見積もり: {rows: ? (?)}
           │ 出力: 64行 (576B) 、ピークメモリ: 8KB (0.07%) 、WallTime: 238.69us (0.10%)
           └ ─ RemoteSource[2]
                  出力: [count2:bigint]
                  見積もり:
                  出力: 32行 (288B) 、PeakMemory: 32KB (0.27%) 、WallTime: 182.82us (0.08%)
                  入力avg.: 4.00行, 入力std.de v.: 264.58%
    
    フラグメント2 [adb:AdbPartitioningHandle{schema=tpch、tableName=customer、dimTable=false、shards=32、tableEngineType=Cstore、partitionColumns=c_custkey、prunedBuckets= empty}]
        出力: 32行 (288B) 、PeakMemory: 6MB、WallTime: 164.00ns、入力: 1500015行 (20.03MB) 、タスクあたり: avg.: 500005.00 std.de v.: 21941.36
        出力レイアウト: [count4]
        Output partitioning: SINGLE []
        集約 (PARTIAL)
        │ 出力: [count4:bigint]
        │ 見積もり: {rows: 1 (8B)}
        │ 出力: 64行 (576B) 、ピークメモリ: 336B (0.00%) 、WallTime: 1.01ms (0.42%)
        │ count_4 := count(*)
        └ ─ INNER Join[('c_nationkey' = 'n_nationkey')][$hashvalue, $hashvalue6]
           │ 出力: []
           │ 見積もり: {行: 302035 (4.61MB)}
           │ 出力: 300285行 (210B) 、ピークメモリ: 641KB (5.29%) 、WallTime: 99.08ms (41.45%)
           │ 左 (プローブ) 入力avg.: 46875.00行, 入力std.de v.: 311.24%
           │ 右 (ビルド) 入力avg.: 0.63行, 入力std.de v.: 264.58%
           │ 配布: REPLICATED
           ├─ ScanProject[table = adb:AdbTableHandle{schema=tpch、tableName=customer、partitionColumnHandles=[c_custkey]}]
           │ 出力: [c_nationkey:integer, $hashvalue:bigint]
           │ 見積もり: {rows: 1500000 (5.72MB)}/{rows: 1500000 (5.72MB)}
           │ 出力: 1500000行 (20.03MB) 、ピークメモリ: 5MB (44.38%) 、WallTime: 68.29ms (28.57%)
           │ $hashvalue := 'combine_hash'(BIGINT '0', COALESCE('$operato r$ hash_code'('c_nationkey'), 0))
           │ c_nationkey := AdbColumnHandle{columnName=c_nationkey, type=4, isIndexed=true}
           │ 入力: 1500000行 (7.15MB) 、フィルター: 0.00%
           └ ─ LocalExchange[HASH][$hashvalue6] ("n_nationkey")
              │ 出力: [n_nationkey:integer, $hashvalue6:bigint]
              │ 見積もり: {rows: 5 (60B)}
              │ 出力: 30行 (420B) 、ピークメモリ: 394KB (3.26%) 、WallTime: 455.03us (0.19%)
              └ ─ プロジェクト []
                 │ 出力: [n_nationkey:integer, $hashvalue10:bigint]
                 │ 見積もり: {rows: 5 (60B)}
                 │ 出力: 15行 (210B) 、ピークメモリ: 24KB (0.20%) 、WallTime: 83.61us (0.03%)
                 │ 入力avg.: 0.63行, 入力std.de v.: 264.58%
                 │ $hashvalue_10 := 'combine_hash'(BIGINT '0', COALESCE('$operato r$ hash_code'('n_nationkey'), 0))
                 └ ─ RemoteSource[3]
                        出力: [n_nationkey: 整数]
                        見積もり:
                        出力: 15行 (75B) 、PeakMemory: 24KB (0.20%) 、WallTime: 45.97us (0.02%)
                        入力avg.: 0.63行, 入力std.de v.: 264.58%
    
    フラグメント3 [adb:AdbPartitioningHandle{schema=tpch, tableName=nation, dimTable=true, shards=32, tableEngineType=Cstore, partitionColumns=, prunedBuckets= empty}]
        出力: 5行 (25B) 、PeakMemory: 185KB、WallTime: 1.00ns、入力: 26行 (489B); タスクごと: avg.: 26.00 std.de v.: 0.00
        出力レイアウト: [n_nationkey]
        出力パーティショニング: BROADCAST []
        INNER Join[('n_regionkey' = 'r_regionkey')][$hashvalue7, $hashvalue8]
        │ 出力: [n_nationkey: 整数]
        │ 見積もり: {rows: 5 (60B)}
        │ 出力: 11行 (64B) 、ピークメモリ: 152KB (1.26%) 、WallTime: 255.86us (0.11%)
        │ 左 (プローブ) 入力avg.: 25.00行, 入力std.de v.: 0.00%
        │ 右 (ビルド) 入力avg.: 0.13行, 入力std.de v.: 264.58%
        │ 配布: REPLICATED
        ├─ ScanProject[table = adb:AdbTableHandle{schema=tpch, tableName=nation, partitionColumnHandles=[]}]
        │ 出力: [n_nationkey:integer, n_regionkey:integer, $hashvalue7:bigint]
        │ 見積もり: {rows: 25 (200B)}/{rows: 25 (200B)}
        │ 出力: 25行 (475B) 、ピークメモリ: 16KB (0.13%) 、WallTime: 178.81us (0.07%)
        │ $hashvalue_7 := 'combine_hash'(BIGINT '0', COALESCE('$operato r$ hash_code'('n_regionkey'), 0))
        │ n_nationkey := AdbColumnHandle{columnName=n_nationkey, type=4, isIndexed=true}
        │ n_regionkey := AdbColumnHandle{columnName=n_regionkey, type=4, isIndexed=true}
        │ 入力: 25行 (250B) 、フィルタリング: 0.00%
        └ ─ LocalExchange[HASH][$hashvalue8] ("r_regionkey")
           │ 出力: [r_regionkey:integer, $hashvalue8:bigint]
           │ 見積もり: {rows: 1 (4B)}
           │ 出力: 2行 (28B) 、PeakMemory: 34KB (0.29%) 、WallTime: 57.41us (0.02%)
           └ ─ ScanProject[table = adb:AdbTableHandle{schema=tpch、tableName=region、partitionColumnHandles=[]}]
                  出力: [r_regionkey:integer, $hashvalue9:bigint]
                  見積もり: {rows: 1 (4B)}/{rows: 1 (4B)}
                  出力: 1行 (14B) 、ピークメモリ: 8KB (0.07%) 、WallTime: 308.99us (0.13%)
                  $hashvalue_9 := 'combine_hash'(BIGINT '0', COALESCE('$operato r$ hash_code'('r_regionkey'), 0))
                  r_regionkey := AdbColumnHandle{columnName=r_regionkey, type=4, isIndexed=true}
                  入力: 1行 (5B) 、フィルタリング: 0.00%
    次の表に、上記の結果の主なパラメーターを示します。
    パラメーター 説明
    出力: [symbol:type] 各演算子の出力列とデータ型。
    見積もり: {rows: % s (% sB)} 各演算子の推定行数とデータ量。 データは、オプティマイザの結合順序付けおよびデータシャフリング技術を決定するために使用することができる。
    PeakMemory: % s メモリ使用量の合計。 このパラメーターは、メモリ使用中に発生するボトルネックの原因を分析するために使用します。
    WallTime: % s 演算子の合計実行時間。 このパラメーターは、コンピューティング操作中に発生するボトルネックの原因を分析するために使用します。
    この期間は、並列計算による実際の実行期間ではありません。
    入力: % s行 (% sB) 入力行数とデータ量。
    1タスクあたり: avg.: % s std.de v.: % s 行の平均数とその標準偏差。 これらのパラメータは、ステージに存在するデータスキューを分析するために使用されます。
    出力: % s row (% sB) 出力行数とデータ量。

シナリオ

EXPLAIN ANALYZEコマンドを実行して、実行計画に関連する一般的な問題を分析できます。
  • フィルターは押し下げられません。
    次のセクションのSQL 1とSQL 2は、2つのSQLクエリを示します。 SQL 1と比較して、SQL 2にはプッシュダウンできないlength(string_test) 関数が含まれています。 SQL 2が実行されると、完全なデータがスキャンされます。
    • SQL 1
      SELECT count(*) FROMテストWHERE string_test = 'a';
    • SQL 2
      SELECT count(*) FROMテストWHERE length(string_test) = 1;
    EXPLAIN ANALYZEコマンドを実行して、上記の2つのSQLクエリの実行計画を分析できます。 次のセクションでは、2つの実行プランのフラグメント2を比較します。
    • SQL 1では、TableScan演算子とInput avgを使用します。 パラメーターは0.00行に設定されます。 これは、フィルタが押し下げられ、走査された行の数がゼロであることを示す。
      フラグメント2 [adb:AdbPartitioningHandle{schema=test4dmp、tableName=test、dimTable=false、shards=4、tableEngineType=Cstore、partitionColumns=id、prunedBuckets= empty}]
          出力: 4行 (36B) 、PeakMemory: 0B、WallTime: 6.00ns、入力: 0行 (0B) 、タスクごと: avg.: 0.00 std.de v.: 0.00
          出力レイアウト: [count_0_1]
          Output partitioning: SINGLE []
          集約 (PARTIAL)
          │ 出力: [count_0_1:bigint]
          │ 見積もり: {rows: 1 (8B)}
          │ 出力: 8行 (72B) 、PeakMemory: 0B (0.00%) 、WallTime: 212.92us (3.99%)
          │ count_0_1 := count(*)
          └ ─ TableScan[adb:AdbTableHandle{schema=test4dmp, tableName=test, partitionColumnHandles=[id]}]
                 出力: []
                 見積もり: {rows: 4 (0B)}
                 出力: 0行 (0B) 、PeakMemory: 0B (0.00%) 、WallTime: 4.76ms (89.12%)
                 入力avg.: 0.00行, 入力std.de v.: ?%
    • SQL 2はScanFilterProject演算子を使用し、Inputパラメーターは9999行に設定されます。 さらに、filterPredicateプロパティは ('test4dmp'.'length ('string_test') = BIGINT '1') に設定されます。 これは、フィルタが押し下げられず、走査された行の数が9999であることを示す。
      フラグメント2 [adb:AdbPartitioningHandle{schema=test4dmp、tableName=test、dimTable=false、shards=4、tableEngineType=Cstore、partitionColumns=id、prunedBuckets= empty}]
          出力: 4行 (36B) 、PeakMemory: 0B、WallTime: 102.00ns、入力: 0行 (0B) 、タスクごと: avg.: 0.00 std.de v.: 0.00
          出力レイアウト: [count_0_1]
          Output partitioning: SINGLE []
          集約 (PARTIAL)
          │ 出力: [count_0_1:bigint]
          │ 見積もり: {rows: 1 (8B)}
          │ 出力: 8行 (72B) 、ピークメモリ: 0B (0.00%) 、WallTime: 252.23us (0.12%)
          │ count_0_1 := count(*)
          └ ─ ScanFilterProject[table = adb:AdbTableHandle{schema=test4dmp, tableName=test, partitionColumnHandles=[id]}, filterPredicate = ('test4dmp'.'length ('string_test') = BIGINT '1')]
                 出力: []
                 見積もり: {rows: 9999 (312.47kB)}/{rows: 9999 (312.47kB)}/{rows: ? (?)}
                 出力: 0行 (0B) 、PeakMemory: 0B (0.00%) 、WallTime: 101.31ms (49.84%)
                 string_test := AdbColumnHandle{columnName=string_test, type=13, isIndexed=true}
                 入力: 9999行 (110.32kB) 、フィルタリング: 100.00%
  • 悪いSQLメモリ使用量

    PeakMemoryパラメーターを使用して、各フラグメントのメモリ使用量の合計を表示し、リソース消費の問題をトラブルシューティングできます。 ディザスタブロードキャストは、高い総メモリ使用量をもたらし得る。 これらのシナリオを除いて、PeakMemoryパラメーターの大きな値は、通常、結合されたデータのブロート、左側の結合されたテーブルの大量のデータ、またはTableScan演算子によってスキャンされた大量のデータによって発生します。 ビジネス要件に基づいて条件を追加して、これらの値を制限する必要があります。 PeakMemoryパラメーターを使用して、各演算子のメモリ使用量の合計を表示し、最も多くのリソースを消費する演算子を特定することもできます。