为了提高性能(例如,对于连接),建议首先计算表的静态值。
在Hive中我可以做::
analyze table <table name> compute statistics;
在黑斑羚:compute stats <table name>;
我的spark应用程序(从hive-tables中读取)是否也受益于预先计算的统计数据?如果是,我需要运行哪一个?他们都在hive metastore中保存数据吗?我使用spark 1.6.1在Cloudera 5.5.4
注意:在spark 1.6.1 (https://spark.apache.org/docs/1.6.1/sql-programming-guide.html)的文档中,对于参数spark.sql.autoBroadcastJoinThreshold
,我发现了一个提示:
注意,目前统计只支持Hive Metastore表,其中命令ANALYZE TABLE COMPUTE STATISTICSNoscan已运行
这里是即将发布的Spark 2.3.0(可能有些特性已经在2.2.1或更早的版本中发布了)。
我的spark应用程序(从hive-tables中读取)是否也受益于预先计算的统计数据?
如果Impala或Hive将Hive metastore中的表统计数据(例如表大小或行数)记录在Spark可以读取的表元数据中(并将其转换为自己的Spark统计数据以进行查询规划),则可以。
您可以通过在spark-shell
中使用DESCRIBE EXTENDED
SQL命令轻松检查。
scala> spark.version
res0: String = 2.4.0-SNAPSHOT
scala> sql("DESC EXTENDED t1 id").show
+--------------+----------+
|info_name |info_value|
+--------------+----------+
|col_name |id |
|data_type |int |
|comment |NULL |
|min |0 |
|max |1 |
|num_nulls |0 |
|distinct_count|2 |
|avg_col_len |4 |
|max_col_len |4 |
|histogram |NULL |
+--------------+----------+
ANALYZE TABLE COMPUTE STATISTICS noscan
计算Spark使用的一个统计数据,即表的总大小(由于noscan
选项,没有行计数指标)。如果Impala和Hive将其记录到"适当"的位置,Spark SQL将在DESC EXTENDED
中显示它。
使用DESC EXTENDED tableName
进行表级统计,看看是否能找到由Impala或Hive生成的数据。如果它们在DESC EXTENDED
的输出中,它们将用于优化连接(并且对于聚合和过滤器也开启了基于成本的优化)。
列的统计数据存储在表属性中(以Spark特有的序列化格式),我真的很怀疑Impala或Hive能够计算这些统计数据并将它们存储在Spark sql兼容的格式中。
我假设您正在使用Hive上的Spark(或)Spark- sql与Hive上下文。如果是这种情况,您应该在hive中运行analyze。
分析table<…>通常需要在表创建后或有重要的插入/更改时运行。如果这是一个MR或spark作业,您可以在加载步骤结束时执行此操作。
在分析时,如果您在spark上使用hive -也请使用下面链接中的配置。您可以在会话级别为每个查询设置它。我已经在生产中使用了这个链接https://cwiki.apache.org/confluence/display/Hive/Hive+on+Spark%3A+Getting+Started中的参数,它工作得很好。
根据我的理解,计算统计在impala上是最新的实现,并将您从调整蜂巢设置中解放出来。
来自官方文档:
如果使用基于hive的方法收集统计信息,请参阅Hive wiki提供Hive的相关配置信息的一面。Cloudera建议使用Impala COMPUTE STATS语句来的潜在配置和可伸缩性问题统计信息收集过程。
如果执行Hive语句ANALYZE TABLE COMPUTE STATISTICS FOR, Impala只能使用结果列统计信息,如果表未分区。Impala不能使用hive生成的列分区表的统计信息。
有用的链接:https://www.cloudera.com/documentation/enterprise/5-5-x/topics/impala_perf_stats.html