Perfil de Apache Doris y explicar en detalle

1. Breve introducción

Ejecute EXPLAIN + SQL en Apache Doris para obtener el plan de consulta correspondiente a SQL. Combinado con el perfil de Apache Doris, puede comprender cómo Doris maneja las declaraciones SQL, que se utiliza para analizar el cuello de botella de rendimiento de las declaraciones o estructuras de consulta, para ayudar a elegir mejores índices y escribir declaraciones de consulta más optimizadas.

2. Análisis del plan

2.1 preparación de SQL

tpcds query96.sql como ejemplo

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 explicar el análisis de resultados

El plan de consulta se puede dividir en plan de ejecución lógico (plan de consulta lógico) y plan de ejecución física (plan de consulta física). El plan de consulta actual se refiere al plan de ejecución lógico de forma predeterminada; el plan de consulta correspondiente a tpcds query96.sql se muestra a continuación.

-- 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 Descripción de atributos comunes

Colocate Join es adecuado para escenarios donde varias tablas se dividen en depósitos según el mismo campo y se unen con frecuencia según el mismo campo. Por ejemplo, muchas aplicaciones de comercio electrónico se dividen en depósitos según el ID del comerciante y con frecuencia se unen según el Identificación del comerciante.

inserte la descripción de la imagen aquí

2.2.2 análisis del plan

inserte la descripción de la imagen aquí

  • El plan de consulta de Query96 se divide en cinco fragmentos de plan, numerados del 0 al 4

  • El plan de consulta de análisis se puede realizar de abajo hacia arriba y analizar uno por uno.

  • El fragmento del plan inferior es el análisis del fragmento 4.

    • Principalmente responsable de escanear la tabla time_dim y ejecutar las condiciones de consulta relacionadas por adelantado, es decir, pushdown de predicados
    • Para la tabla de agregación (Clave de agregación), Doris elegirá si habilitar PREAGGREGACIÓN de acuerdo con diferentes consultas. La preagregación de time_dim en la figura anterior está desactivada. Cuando se desactiva, se leerán todas las columnas de dimensión de time_dim. Cuando hay muchas columnas de dimensiones en la tabla, esto puede convertirse en un factor clave que afecta el rendimiento.
    • Si la tabla time_dim selecciona Partición de rango para la partición de datos, las particiones en el Plan de consulta indicarán cuántas particiones alcanza la consulta y el filtrado automático de particiones irrelevantes reducirá efectivamente la cantidad de datos escaneados.
    • Si hay una vista materializada, Doris seleccionará automáticamente la vista materializada de acuerdo con la consulta. Si no hay una vista materializada, la consulta llegará automáticamente a la tabla base, que es el resumen: time_dim que se muestra en la figura anterior. Puede consultar a doris para probar la vista materializada
    • Cuando se complete el escaneo de datos time_dim, finalizará el proceso de ejecución del Fragmento 4. En este momento, pasará los datos escaneados a sus otros Fragmentos. ID DE INTERCAMBIO: 09 significa que los datos se pasan al nodo receptor etiquetado como 9, que se puede pasar la vista gráfica
  • Para el Plan de consulta de Query96, los Fragmentos 2, 3 y 4 tienen funciones similares, pero las tablas responsables del escaneo son diferentes; específicamente, los operadores Orden/Agregación/Unión en la consulta se realizan todos en el Fragmento 1, y el análisis del Fragmento 1 esta enfocado

    • El fragmento 1 integra la ejecución de tres operadores de unión y utiliza el método BROADCAST predeterminado para la ejecución, es decir, la tabla pequeña se transmite a la tabla grande. Si las dos tablas de unión son tablas grandes, se recomienda utilizar el método SHUFFLE.
    • En la actualidad, Doris solo admite HASH JOIN, es decir, el algoritmo hash se utiliza para unirse.
    • Hay un campo de colocación, que se utiliza para indicar que las dos tablas de unión adoptan el mismo método de partición/depósito, de modo que el proceso de unión se pueda ejecutar directamente localmente sin movimiento de datos.
    • Una vez completada la ejecución de Join, se deben ejecutar los operadores mencionados anteriormente de Agregación, Orden por y TOP-N.

3. Breve introducción de Doris-Profile

Puede ver los detalles de ejecución de la tarea a través del módulo QueryProfile en la página 8030. Lo siguiente es parte del QueryProfile realmente ejecutado por query96.sql. Para obtener detalles sobre el nombre de cada indicador, consulte: Análisis de consultas de 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
  • Activo: indica el tiempo de ejecución del nodo (incluidos todos sus nodos secundarios)
  • BuildTime: el momento de escanear la tabla correcta y construir la tabla hash
  • ProbeTime: el momento para obtener la tabla de la izquierda y buscar en la tabla hash coincidencias y resultados

Supongo que te gusta

Origin blog.csdn.net/ith321/article/details/132006439
Recomendado
Clasificación