使用ANALYZE TABLE命令的Spark与Hive差异-

时间:2019-01-04 20:38:27

标签: apache-spark pyspark apache-spark-sql pyspark-sql

从Spark在Hive表上运行的ANALYZE TABLE命令不能提供与从Hive发出的同一命令相同的性能改进。

例如,我已将一个数据框插入到一个空的Hive表中:-

output.write.insertInto(“XXXXXXXX”)

,然后运行分析表命令:-

spark.sql("ANALYZE TABLE XXXXXXXX COMPUTE STATISTICS")

当我在Hive中进行记录计数时,它非常慢:-

select count(*) from XXXXXXXX;
+-----------+
|    _c0    |
+-----------+
| 12345678  |
+-----------+
1 row selected (36.038 seconds)

但是,如果我直接在Hive中运行同一分析表命令,性能会提高:-

select count(*) from XXXXXXXX;
+-----------+
|    _c0    |
+-----------+
| 12345678  |
+-----------+
1 row selected (0.096 seconds)

谁能解释为什么会出现这种差异? 有解决方法吗?

1 个答案:

答案 0 :(得分:0)

这是因为火花很愚蠢。 Spark的ANALYZE TABLE命令仅以Spark兼容格式将计算出的统计信息写入Hive不知道的表属性中。编写时,Spark会完全忽略标准的Hive表统计信息。

如果您进行

show create table XXXXXXXX

在Hive中,在查询中执行spark.sql(“ ANALYZE ..”)步骤之后,您将在tbl_properties部分中看到以下内容:

TBLPROPERTIES ( 
  'numFiles'='1', 
  'numRows'='-1', 
  'rawDataSize'='-1', 
  'spark.sql.statistics.numRows'='12345678', 
  'spark.sql.statistics.totalSize'='12345678', 
  'totalSize'='12345678', 

仅在配置单元中执行相同的命令后,您才会获得正确的信息:

TBLPROPERTIES ( 
  'numFiles'='1', 
  'numRows'='12345678', 
  'rawDataSize'='12345678', 
  'spark.sql.statistics.numRows'='12345678', 
  'spark.sql.statistics.totalSize'='12345678', 
  'totalSize'='12345678', 

在计算统计信息时,Spark可以正确填充numRows和rawDataSize字段吗?大概。为什么不这样做?不知道。 :(可能是spark开发人员在上面对像Hive这样的低端系统进行了优化(即使Apache Impala之类的其他框架也可以从此处的正确统计信息中受益-因为Impala正确使用了它们)

唯一的解决方法是在执行Spark Statistics统计信息命令之后执行相应的配置单元任务,这非常丑陋。 :(