Apache Doris プロフィール&詳しく解説

1. 簡単な紹介

Apache Doris で EXPLAIN + SQL を実行して、SQL に対応するクエリ プランを取得します。Apache Doris のプロファイルと組み合わせると、Doris が SQL ステートメントをどのように処理するかを理解できます。これは、クエリ ステートメントや構造のパフォーマンスのボトルネックを分析するために使用されます。より適切なインデックスを選択し、より最適化されたクエリ ステートメントを作成するのに役立ちます。

2. 計画分析

2.1 SQLの準備

tpcds query96.sql の例

explain
-- explain graph 生成对应执行计划图表
select  count(*)
from store_sales
    ,household_demographics
    ,time_dim
    , store
where ss_sold_time_sk = time_dim.t_time_sk
    and ss_hdemo_sk = household_demographics.hd_demo_sk
    and ss_store_sk = s_store_sk
    and time_dim.t_hour = 8
    and time_dim.t_minute >= 30
    and household_demographics.hd_dep_count = 5
    and store.s_store_name = 'ese'
order by count(*) limit 100;

2.2 結果分析の説明

クエリ プランは論理的な実行プラン (Logical Query Plan) と物理的な実行プラン (Physical Query Plan) に分けられます。現在のクエリ プランはデフォルトで論理的な実行プランを指します。tpcds query96.sql に対応するクエリ プランを以下に示します。

-- graph 
                                         ┌───────────────┐[8: ResultSink][Fragment: 4]
                                        │RESULT SINK    │
                                        └───────────────┘
                                         ┌─────────────┐[8: TOP-N][Fragment: 4]
                                         └─────────────┘
                               ┌────────────────────────────────┐[13: AGGREGATE (merge finalize)][Fragment: 4]
                               └────────────────────────────────┘
                                        ┌──────────────┐[12: EXCHANGE][Fragment: 4]
                                        └──────────────┘
                                     ┌────────────────────┐[12: DataStreamSink][Fragment: 0]
                                     │STREAM DATA SINK    │
                                     │  EXCHANGE ID: 12
                                     │  UNPARTITIONED     │
                                     └────────────────────┘
                               ┌─────────────────────────────────┐[7: AGGREGATE (update serialize)][Fragment: 0]
                               └─────────────────────────────────┘
                                ┌───────────────────────────────┐[6: HASH JOIN][Fragment: 0]join op: INNER JOIN (BROADCAST)
                                └───────────────────────────────┘
                                    ┌───────────┴─────────────────────────────────────┐
                                    │                                                 │
                    ┌───────────────────────────────┐                         ┌──────────────┐[4: HASH JOIN]                 │                         │[11: EXCHANGE][Fragment: 0]                  │                         │[Fragment: 0]join op: INNER JOIN (BROADCAST)│                         └──────────────┘
                    └───────────────────────────────┘                                 │
                    ┌───────────────┴─────────────────────┐                           │
                    │                                     │                ┌────────────────────┐
    ┌───────────────────────────────┐             ┌──────────────┐         │[11: DataStreamSink][2: HASH JOIN]                 │             │[10: EXCHANGE]│         │[Fragment: 3][Fragment: 0]                  │             │[Fragment: 0] │         │STREAM DATA SINK    │join op: INNER JOIN (BROADCAST)│             └──────────────┘         │  EXCHANGE ID: 11
    └───────────────────────────────┘                     │                │  UNPARTITIONED     │
          ┌─────────┴──────────┐                          │                └────────────────────┘
          │                    │               ┌────────────────────┐                ┌┘
┌──────────────────┐    ┌─────────────┐        │[10: DataStreamSink]│                │[0: OlapScanNode] │    │[9: EXCHANGE]│        │[Fragment: 2]       │       ┌─────────────────┐[Fragment: 0]     │    │[Fragment: 0]│        │STREAM DATA SINK    │       │[5: OlapScanNode]TABLE: store_sales│    └─────────────┘        │  EXCHANGE ID: 10   │       │[Fragment: 3]
└──────────────────┘           │               │  UNPARTITIONED     │       │TABLE: store     │
                               │               └────────────────────┘       └─────────────────┘
                     ┌───────────────────┐                │[9: DataStreamSink]│                │[Fragment: 1]      │ ┌─────────────────────────────┐
                     │STREAM DATA SINK   │ │[3: OlapScanNode]
                     │  EXCHANGE ID: 09  │ │[Fragment: 2]
                     │  UNPARTITIONED    │ │TABLE: household_demographics│
                     └───────────────────┘ └─────────────────────────────┘
                      ┌─────────────────┐[1: OlapScanNode][Fragment: 1]TABLE: time_dim  │
                      └─────────────────┘

-- 非graph 
PLAN FRAGMENT 0
 OUTPUT EXPRS:<slot 11> <slot 10> count(*)
  PARTITION: UNPARTITIONED

  RESULT SINK

  8:TOP-N
  |  order by: <slot 11> <slot 10> count(*) ASC
  |  offset: 0
  |  limit: 100
  |  
  13:AGGREGATE (merge finalize)
  |  output: count(<slot 10> count(*))
  |  group by: 
  |  cardinality=-1
  |  
  12:EXCHANGE

PLAN FRAGMENT 1
 OUTPUT EXPRS:
  PARTITION: HASH_PARTITIONED: `default_cluster:tpcds`.`store_sales`.`ss_item_sk`, `default_cluster:tpcds`.`store_sales`.`ss_ticket_number`

  STREAM DATA SINK
    EXCHANGE ID: 12
    UNPARTITIONED

  7:AGGREGATE (update serialize)
  |  output: count(*)
  |  group by: 
  |  cardinality=1
  |  
  6:HASH JOIN
  |  join op: INNER JOIN (BROADCAST)
  |  hash predicates:
  |  colocate: false, reason: Tables are not in the same group
  |  equal join conjunct: `ss_store_sk` = `s_store_sk`
  |  runtime filters: RF000[in] <- `s_store_sk`
  |  cardinality=2880403
  |  
  |----11:EXCHANGE
  |    
  4:HASH JOIN
  |  join op: INNER JOIN (BROADCAST)
  |  hash predicates:
  |  colocate: false, reason: Tables are not in the same group
  |  equal join conjunct: `ss_hdemo_sk` = `household_demographics`.`hd_demo_sk`
  |  runtime filters: RF001[in] <- `household_demographics`.`hd_demo_sk`
  |  cardinality=2880403
  |  
  |----10:EXCHANGE
  |    
  2:HASH JOIN
  |  join op: INNER JOIN (BROADCAST)
  |  hash predicates:
  |  colocate: false, reason: Tables are not in the same group
  |  equal join conjunct: `ss_sold_time_sk` = `time_dim`.`t_time_sk`
  |  runtime filters: RF002[in] <- `time_dim`.`t_time_sk`
  |  cardinality=2880403
  |  
  |----9:EXCHANGE
  |    
  0:OlapScanNode
     TABLE: store_sales
     PREAGGREGATION: OFF. Reason: conjunct on `ss_sold_time_sk` which is StorageEngine value column
     PREDICATES: `default_cluster:tpcds.store_sales`.`__DORIS_DELETE_SIGN__` = 0
     runtime filters: RF000[in] -> `ss_store_sk`, RF001[in] -> `ss_hdemo_sk`, RF002[in] -> `ss_sold_time_sk`
     partitions=1/1
     rollup: store_sales
     tabletRatio=3/3
     tabletList=20968,20972,20976
     cardinality=2880403
     avgRowSize=67.95811
     numNodes=3

PLAN FRAGMENT 2
 OUTPUT EXPRS:
  PARTITION: HASH_PARTITIONED: `default_cluster:tpcds`.`store`.`s_store_sk`

  STREAM DATA SINK
    EXCHANGE ID: 11
    UNPARTITIONED

  5:OlapScanNode
     TABLE: store
     PREAGGREGATION: OFF. Reason: null
     PREDICATES: `store`.`s_store_name` = 'ese', `default_cluster:tpcds.store`.`__DORIS_DELETE_SIGN__` = 0
     partitions=1/1
     rollup: store
     tabletRatio=3/3
     tabletList=20773,20777,20781
     cardinality=23
     avgRowSize=1798.8695
     numNodes=3

PLAN FRAGMENT 3
 OUTPUT EXPRS:
  PARTITION: HASH_PARTITIONED: `default_cluster:tpcds`.`household_demographics`.`hd_demo_sk`

  STREAM DATA SINK
    EXCHANGE ID: 10
    UNPARTITIONED

  3:OlapScanNode
     TABLE: household_demographics
     PREAGGREGATION: OFF. Reason: null
     PREDICATES: `household_demographics`.`hd_dep_count` = 5, `default_cluster:tpcds.household_demographics`.`__DORIS_DELETE_SIGN__` = 0
     partitions=1/1
     rollup: household_demographics
     tabletRatio=3/3
     tabletList=20848,20852,20856
     cardinality=14399
     avgRowSize=2.8781166
     numNodes=3

PLAN FRAGMENT 4
 OUTPUT EXPRS:
  PARTITION: HASH_PARTITIONED: `default_cluster:tpcds`.`time_dim`.`t_time_sk`

  STREAM DATA SINK
    EXCHANGE ID: 09
    UNPARTITIONED

  1:OlapScanNode
     TABLE: time_dim
     PREAGGREGATION: OFF. Reason: null
     PREDICATES: `time_dim`.`t_hour` = 8, `time_dim`.`t_minute` >= 30, `default_cluster:tpcds.time_dim`.`__DORIS_DELETE_SIGN__` = 0
     partitions=1/1
     rollup: time_dim
     tabletRatio=3/3
     tabletList=20713,20717,20721
     cardinality=172799
     avgRowSize=11.671202
     numNodes=3

2.2.1 共通属性の説明

Colocate Join は、複数のテーブルが同じフィールドに従ってバケットに分割され、同じフィールドに基づいて頻繁に結合されるシナリオに適しています。たとえば、多くの電子商取引アプリケーションは、マーチャント ID に従ってバケットに分割され、マーチャント ID に従って頻繁に結合されます。販売者ID。

ここに画像の説明を挿入

2.2.2 計画分析

ここに画像の説明を挿入

  • Query96 のクエリ プランは、0 から 4 までの番号が付けられた 5 つのプラン フラグメントに分割されています。

  • 分析クエリプランはボトムアップ方式で実行でき、1つずつ分析できます。

  • 一番下の計画フラグメントはフラグメント 4 の分析です

    • 主に time_dim テーブルをスキャンし、関連するクエリ条件を事前に実行する (述語プッシュダウン) ことを担当します。
    • 集計テーブル (集計キー) について、doris はさまざまなクエリに応じて PREAGGREGATION を有効にするかどうかを選択します。上図の time_dim の事前集計はオフになっています。オフにすると、time_dim のすべてのディメンション列が読み取られます。テーブルに多くのディメンション列がある場合、これがパフォーマンスに影響を与える重要な要素になる可能性があります。
    • time_dim テーブルでデータ パーティション化に範囲パーティションを選択した場合、クエリ プラン内のパーティションはクエリがヒットしたパーティションの数を示し、無関係なパーティションの自動フィルタリングにより、スキャンされるデータの量が効果的に削減されます。
    • マテリアライズド ビューがある場合、doris はクエリに従ってマテリアライズド ビューを自動的に選択します。マテリアライズド ビューがない場合、クエリは自動的にベース テーブル (上図に示すロールアップ: time_dim) にヒットします。マテリアライズドビューをテストするためにドリスに送信
    • time_dim データ スキャンが完了すると、フラグメント 4 の実行プロセスが終了します。この時点で、スキャンされたデータが他のフラグメントに渡されます。EXCHANGE ID: 09 は、データが 9 というラベルの受信ノードに渡されることを意味します。グラフビューを渡すことができます
  • Query96 のクエリ プランの場合、フラグメント 2、3、および 4 は同様の機能を持ちますが、スキャンを担当するテーブルが異なります。具体的には、クエリ内の Order/Aggregation/Join 演算子はすべてフラグメント 1 で実行され、フラグメント 1 の分析は実行されます。集中している

    • フラグメント 1 は、実行にデフォルトの BROADCAST メソッドを使用して 3 つの結合演算子の実行を統合します。つまり、小さなテーブルが大きなテーブルにブロードキャストされます。2 つの結合テーブルが両方とも大きなテーブルである場合は、SHUFFLE メソッドを使用することをお勧めします。
    • 現在、doris は HASH JOIN のみをサポートしています。つまり、結合にはハッシュ アルゴリズムが使用されます。
    • colocate フィールドがあり、2 つの結合テーブルが同じパーティション/バケット方式を採用していることを示すために使用され、データを移動せずに結合プロセスをローカルで直接実行できます。
    • Joinの実行が完了したら、上記のAggregation、Order by、TOP-Nの演算子を実行します。

3. ドリスプロフィールの簡単な紹介

8030 ページの QueryProfile モジュールを介してタスク実行の詳細を表示できます。以下は、query96.sql によって実際に実行される QueryProfile の一部です。各インジケーター名の詳細については、「Apache Doris クエリ分析」を参照してください

Query:
    Summary:
          -  Query  ID:  7dd4ba245012441c-b0aadbed39f80f20
          -  Start  Time:  2022-04-15  15:52:22
          -  End  Time:  2022-04-15  15:52:22
          -  Total:  611ms
          -  Query  Type:  Query
          -  Query  State:  EOF
          -  Doris  Version:  0.15.0-rc04
          -  User:  root
          -  Default  Db:  default_cluster:tpcds
          -  Sql  Statement:  /*  ApplicationName=DBeaver  Enterprise  7.0.0  -  SQLEditor  <20220321常用命令-doris.sql>  */  select    count(*)
from  store_sales
        ,household_demographics
        ,time_dim
        ,  store
where  ss_sold_time_sk  =  time_dim.t_time_sk
        and  ss_hdemo_sk  =  household_demographics.hd_demo_sk
        and  ss_store_sk  =  s_store_sk
        and  time_dim.t_hour  =  8
        and  time_dim.t_minute  >=  30
        and  household_demographics.hd_dep_count  =  5
        and  store.s_store_name  =  'ese'
order  by  count(*)  limit  100
          -  Is  Cached:  No
        Execution  Summary:
              -  Analysis  Time:  636.648us
              -  Plan  Time:  19.230ms
              -  Schedule  Time:  125.121ms
              -  Wait  and  Fetch  Result  Time:  466.30ms
    Execution  Profile  7dd4ba245012441c-b0aadbed39f80f20:(Active:  611.44ms,  %  non-child:  100.00%)
        Fragment  0:
            Instance  7dd4ba245012441c-b0aadbed39f80f2d  (host=TNetworkAddress(hostname:10.192.119.70,  port:9060)):(Active:  586.950ms,  %  non-child:  0.00%)
                  -  FragmentCpuTime:  756.962us
                  -  MemoryLimit:  2.00  GB
                  -  PeakMemoryUsage:  48.01  KB
                  -  PeakReservation:  0.00  
                  -  PeakUsedReservation:  0.00  
                  -  RowsProduced:  1
                BlockMgr:
                      -  BlockWritesOutstanding:  0
                      -  BlocksCreated:  0
                      -  BlocksRecycled:  0
                      -  BufferedPins:  0
                      -  BytesWritten:  0.00  
                      -  MaxBlockSize:  8.00  MB
                      -  TotalBufferWaitTime:  0ns
                      -  TotalEncryptionTime:  0ns
                      -  TotalIntegrityCheckTime:  0ns
                      -  TotalReadBlockTime:  0ns
                DataBufferSender  (dst_fragment_instance_id=7dd4ba245012441c-b0aadbed39f80f2d):
                      -  AppendBatchTime:  124.481us
                          -  ResultSendTime:  119.257us
                          -  TupleConvertTime:  4.217us
                      -  NumSentRows:  1
                SORT_NODE  (id=8):(Active:  587.36ms,  %  non-child:  0.01%)
                      -  PeakMemoryUsage:  16.00  KB
                      -  RowsReturned:  1
                      -  RowsReturnedRate:  1
                    AGGREGATION_NODE  (id=13):(Active:  586.958ms,  %  non-child:  0.10%)
                          -  Probe  Method:  HashTable  Linear  Probing
                          -  BuildTime:  10.533us
                          -  GetResultsTime:  0ns
                          -  HTResize:  0
                          -  HTResizeTime:  0ns
                          -  HashBuckets:  0
                          -  HashCollisions:  0
                          -  HashFailedProbe:  0
                          -  HashFilledBuckets:  0
                          -  HashProbe:  0
                          -  HashTravelLength:  0
                          -  LargestPartitionPercent:  0
                          -  MaxPartitionLevel:  0
                          -  NumRepartitions:  0
                          -  PartitionsCreated:  0
                          -  PeakMemoryUsage:  28.00  KB
                          -  RowsProcessed:  0
                          -  RowsRepartitioned:  0
                          -  RowsReturned:  1
                          -  RowsReturnedRate:  1
                          -  SpilledPartitions:  0
                        EXCHANGE_NODE  (id=12):(Active:  586.364ms,  %  non-child:  95.96%)
                              -  BytesReceived:  32.00  B
                              -  ConvertRowBatchTime:  7.320us
                              -  DataArrivalWaitTime:  586.282ms
                              -  DeserializeRowBatchTimer:  22.637us
                              -  FirstBatchArrivalWaitTime:  349.530ms
                              -  PeakMemoryUsage:  12.01  KB
                              -  RowsReturned:  3
                              -  RowsReturnedRate:  5
                              -  SendersBlockedTotalTimer(*):  0ns
        Fragment  1:
            Instance  7dd4ba245012441c-b0aadbed39f80f23  (host=TNetworkAddress(hostname:10.192.119.68,  port:9060)):(Active:  472.511ms,  %  non-child:  0.10%)
                  -  FragmentCpuTime:  5.714ms
                  -  MemoryLimit:  2.00  GB
                  -  PeakMemoryUsage:  610.00  KB
                  -  PeakReservation:  0.00  
                  -  PeakUsedReservation:  0.00  
                  -  RowsProduced:  1
                BlockMgr:
                      -  BlockWritesOutstanding:  0
                      -  BlocksCreated:  0
                      -  BlocksRecycled:  0
                      -  BufferedPins:  0
                      -  BytesWritten:  0.00  
                      -  MaxBlockSize:  8.00  MB
                      -  TotalBufferWaitTime:  0ns
                      -  TotalEncryptionTime:  0ns
                      -  TotalIntegrityCheckTime:  0ns
                      -  TotalReadBlockTime:  0ns
                DataStreamSender  (dst_id=12,  dst_fragments=[7dd4ba245012441c-b0aadbed39f80f2d]):(Active:  186.357us,  %  non-child:  0.03%)
                      -  BytesSent:  16.00  B
                      -  IgnoreRows:  0
                      -  LocalBytesSent:  0.00  
                      -  OverallThroughput:  83.84375  KB/sec
                      -  PeakMemoryUsage:  16.00  KB
                      -  SerializeBatchTime:  7.0us
                      -  UncompressedRowBatchSize:  16.00  B
                AGGREGATION_NODE  (id=7):(Active:  471.713ms,  %  non-child:  0.14%)
                      -  Probe  Method:  HashTable  Linear  Probing
                      -  BuildTime:  45.223us
                      -  GetResultsTime:  0ns
                      -  HTResize:  0
                      -  HTResizeTime:  0ns
                      -  HashBuckets:  0
                      -  HashCollisions:  0
                      -  HashFailedProbe:  0
                      -  HashFilledBuckets:  0
                      -  HashProbe:  0
                      -  HashTravelLength:  0
                      -  LargestPartitionPercent:  0
                      -  MaxPartitionLevel:  0
                      -  NumRepartitions:  0
                      -  PartitionsCreated:  0
                      -  PeakMemoryUsage:  280.00  KB
                      -  RowsProcessed:  0
                      -  RowsRepartitioned:  0
                      -  RowsReturned:  1
                      -  RowsReturnedRate:  2
                      -  SpilledPartitions:  0
                    HASH_JOIN_NODE  (id=6):(Active:  470.881ms,  %  non-child:  0.08%)
                          -  ExecOption:  Hash  Table  Built  Asynchronously
                          -  BuildBuckets:  1.024K  (1024)
                          -  BuildRows:  1
                          -  BuildTime:  1.129ms
                          -  HashTableMaxList:  1
                          -  HashTableMinList:  1
                          -  LoadFactor:  4562146422526312400.00
                          -  PeakMemoryUsage:  308.00  KB
                          -  ProbeRows:  341
                          -  ProbeTime:  34.697us
                          -  PushDownComputeTime:  156.171us
                          -  PushDownTime:  4.423us
                          -  RowsReturned:  341
                          -  RowsReturnedRate:  724
  • アクティブ: ノード (そのすべての子ノードを含む) の実行時間を示します。
  • BuildTime: 適切なテーブルをスキャンしてハッシュ テーブルを構築する時間
  • ProbeTime: 左側のテーブルを取得し、一致するハッシュテーブルを検索して出力する時間

おすすめ

転載: blog.csdn.net/ith321/article/details/132006439