在上一篇文章中,我们介绍了Impala query profie
的概要部分,在本篇文章我们介绍Profile
的查询计划(Query Plan
)和执行概要(Execution Summary
)部分。
Profile
的查询计划和执行概要如下所示:
Query (id=36433472787e1cab:29c30e7800000000):
Summary:
....Skipped here....
Plan:
----------------
Max Per-Host Resource Reservation: Memory=0B
Per-Host Resource Estimates: Memory=52.00MB
WARNING: The following tables are missing relevant table and/or column statistics.
default.sample_07
F01:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
| Per-Host Resources: mem-estimate=10.00MB mem-reservation=0B
PLAN-ROOT SINK
| mem-estimate=0B mem-reservation=0B
|
03:AGGREGATE [FINALIZE]
| output: count:merge(*)
| mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB
| tuple-ids=1 row-size=8B cardinality=1
|
02:EXCHANGE [UNPARTITIONED]
| mem-estimate=0B mem-reservation=0B
| tuple-ids=1 row-size=8B cardinality=1
|
F00:PLAN FRAGMENT [RANDOM] hosts=1 instances=1
Per-Host Resources: mem-estimate=42.00MB mem-reservation=0B
01:AGGREGATE
| output: count(*)
| mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB
| tuple-ids=1 row-size=8B cardinality=1
|
00:SCAN HDFS [default.sample_07, RANDOM]
partitions=1/1 files=1 size=44.98KB
stats-rows=unavailable extrapolated-rows=disabled
table stats: rows=unavailable size=44.98KB
column stats: all
mem-estimate=32.00MB mem-reservation=0B
tuple-ids=0 row-size=0B cardinality=unavailable
----------------
Estimated Per-Host Mem: 54525952
Tables Missing Stats: default.sample_07
Per Host Min Reservation: nightly514-3.vpc.cloudera.com:22000(0) nightly514-4.vpc.cloudera.com:22000(0)
Request Pool: root.hive
Admission result: Admitted immediately
ExecSummary:
Operator Hosts Avg Time Max Time #Rows Est. #Rows Peak Mem Est. Peak Mem Detail
-----------------------------------------------------------------------------------------------------------
03:AGGREGATE 1 0.000ns 0.000ns 1 1 20.00 KB 10.00 MB FINALIZE
02:EXCHANGE 1 868.991ms 868.991ms 1 1 0 0 UNPARTITIONED
01:AGGREGATE 1 0.000ns 0.000ns 1 1 16.00 KB 10.00 MB
00:SCAN HDFS 1 743.001ms 743.001ms 823 -1 80.00 KB 32.00 MB default.sample_07
接下来我们来逐一提取和介绍上面Profile
片段中的信息:
1、表/列统计信息:
Max Per-Host Resource Reservation: Memory=0B
Per-Host Resource Estimates: Memory=52.00MB
WARNING: The following tables are missing relevant table and/or column statistics.
default.sample_07
前两行仅说明资源信息,它们不是很重要,也不经常使用。
但是,下一行非常重要,因为Impala
告诉我们是否检测到查询所涉及的表具有最新的统计信息,这一点非常关键,因为Impala
使用表/列统计信息(table/column statistics information
)来进行资源预估(resource estimation
),并执行查询计划来确定运行查询的最佳策略,如果统计信息不是最新的,Impala
最终将使用错误的查询计划,从而影响整体查询性能。
在上面的示例中,我们可以看到default.sample_07
表缺少统计信息,Impala
在查询计划中给出了警告来提示用户需要在该表上执行COMPUTE STATS
来消除这个警告信息。关于表统计的更多信息,请参阅Table and Column Statistics。
2、查询计划详情:
F01:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
| Per-Host Resources: mem-estimate=10.00MB mem-reservation=0B
PLAN-ROOT SINK
| mem-estimate=0B mem-reservation=0B
|
03:AGGREGATE [FINALIZE]
| output: count:merge(*)
| mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB
| tuple-ids=1 row-size=8B cardinality=1
|
02:EXCHANGE [UNPARTITIONED]
| mem-estimate=0B mem-reservation=0B
| tuple-ids=1 row-size=8B cardinality=1
|
F00:PLAN FRAGMENT [RANDOM] hosts=1 instances=1
Per-Host Resources: mem-estimate=42.00MB mem-reservation=0B
01:AGGREGATE
| output: count(*)
| mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB
| tuple-ids=1 row-size=8B cardinality=1
|
00:SCAN HDFS [default.sample_07, RANDOM]
partitions=1/1 files=1 size=44.98KB
stats-rows=unavailable extrapolated-rows=disabled
table stats: rows=unavailable size=44.98KB
column stats: all
mem-estimate=32.00MB mem-reservation=0B
tuple-ids=0 row-size=0B cardinality=unavailable
查询计划(Query plan
)是Impala profile
中最重要的部分之一,我们需要知道如何读取它,因为它告诉我们如何扫描(scan
)表、交换数据(data exchange
)和连接(join
)以获得最终结果。
如果查询很复杂,查询计划也可能会变得非常复杂,让我们从这个简单的查询开始,以了解它的基本信息。需要记住的一件事是,我们需要反向阅读这些信息,来理解Impala
的执行计划。
2.1、HDFS 扫描:
第一步通常从HDFS
扫描(HDFS Scan
)开始:
00:SCAN HDFS [default.sample_07, RANDOM]
partitions=1/1 files=1 size=44.98KB
stats-rows=unavailable extrapolated-rows=disabled
table stats: rows=unavailable size=44.98KB
column stats: all
mem-estimate=32.00MB mem-reservation=0B
tuple-ids=0 row-size=0B cardinality=unavailable
从上面的片段中我们可以获取下面这些有用的信息:
Impala
也读取一个分区。这并不一定意味着这个表是分区的,如果表没有分区,它也将显示为1/1files=1
)Impala
读取的数据总大小为44.98KB
stats-rows=unavailable, table stats: rows=unavailable, cardinality=unavailable
)32MB
,没有内存被预留2.2、Aggregation操作:
HDFS
扫描完成后,Impala
需要做聚合(Aggregation
),因为我们的SQL
语句中使用了COUNT(*)
:
01:AGGREGATE
| output: count(*)
| mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB
| tuple-ids=1 row-size=8B cardinality=1
这里没有太多要解释的,这个步骤执行的是聚合操作。
2.3、Fragment信息:
F00:PLAN FRAGMENT [RANDOM] hosts=1 instances=1
Per-Host Resources: mem-estimate=42.00MB mem-reservation=0B
00:SCAN HDFS
和01:AGGREGATE
片段上的SCAN
和Aggregation
操作都属于片段(FRAGMENT)F00
,它在一个主机和一个实例上运行。F00
这个片段ID
可以用来在Profile
的后面部分找到实际的片段统计信息,它可以告诉我们这个片段在运行时如何运行的详细信息。我们还将在本系列的后面部分讨论这个问题。
2.4、Exchange操作:
02:EXCHANGE [UNPARTITIONED]
| mem-estimate=0B mem-reservation=0B
| tuple-ids=1 row-size=8B cardinality=1
在每个工作节点(worker node
)上完成聚合之后,需要将每个工作节点的结果交换给协调器节点(coordinator
),这个步骤主要做的是这个操作,之后,协调器节点需要对这些结果进行最后的汇总/合并(aggregation/merger
):
03:AGGREGATE [FINALIZE]
| output: count:merge(*)
| mem-estimate=10.00MB mem-reservation=0B spill-buffer=2.00MB
| tuple-ids=1 row-size=8B cardinality=1
以上两个操作都属于同一个片段01
,该片段又可以用来引用Profile
数据的其余部分,以获取关于查询的更详细的统计信息:
F01:PLAN FRAGMENT [UNPARTITIONED] hosts=1 instances=1
现在,让我们来看看Profile
的执行概要部分:
Operator #Hosts Avg Time Max Time #Rows Est. #Rows Peak Mem Est. Peak Mem Detail
-----------------------------------------------------------------------------------------------------------
03:AGGREGATE 1 999.992us 999.992us 1 1 20.00 KB 10.00 MB FINALIZE
02:EXCHANGE 1 831.992ms 831.992ms 1 1 0 0 UNPARTITIONED
01:AGGREGATE 1 0.000ns 0.000ns 1 1 16.00 KB 10.00 MB
00:SCAN HDFS 1 709.995ms 709.995ms 823 -1 80.00 KB 32.00 MB default.sample_07
在这里你可以找到这些有用的信息:
worker
节点运行作业时存在不平衡/倾斜(in-balance/skew
)情况,从理论上讲,它们应该处理相同数量的数据,所有节点应该在相同的时间范围内完成任务#Row
表示运行查询后实际返回的行数,Est. #Rows
表示Impala
根据表统计数据计算出的估计行数。如果#Row
和Est. #Rows
相差较大,就表明Impala
中的表统计信息已经过时。在案例中,SCAN HDFS
操作的Est. #Rows
值为-1
,#Rows
的值为823
,就我们的测试表而言,我们没有表统计信息,因此Impala
报告了-1
的估算值。如果估计值(estimated value
)是正数,但仍与实际返回的行数不同,我们就需要对该表运行COMPUTE STATS
以更新统计信息#Hosts
列告诉我们,有多少工作节点参与了查询中的相关操作。在我的例子中,由于数据很小,我们只有一个主机来运行查询Peak Mem
和Est. Peak Mem
是不言自明的,它们表示实际使用的内存与Impala
根据表统计数据计算出的估计内存如果查询中有连接(join
)操作,Profile
的总结信息中还将向我们展示连接操作中使用了什么连接策略:广播连接(Broadcast Join
)还是随机连接(Shuffle Join
)。在本系列的最后一部分,我将用一个更复杂的query profile
让大家了解更多信息。