首页 > 解决方案 > spark.sql.cbo.enabled=true 与 Hive 表

问题描述

在 Spark 2.2 中,启用了基于成本的优化器选项。文档似乎在说我们需要在启用此选项之前分析 Spark 中的表。我想知道当我们将所有来自 Hive 的表数据作为数据存储层时,此选项是否有用。由于 spark 将使用 Hivetablescan(避免 Map/Reduce)读取 Hive,因此在从 Hive 读取数据时使用 CBO 配置是否有意义。

标签: apache-sparkapache-spark-sql

解决方案


1 班轮:

是的 CBO (spark.sql.cbo.enabled=true) 对 Hive 表也很有用。

解释:

Spark 中的 HiveTable 由HiveTableRelation类表示。Spark 表(或 DataSource 表)由LogicalRelation类表示。这两个类都扩展了 LeadNode。Spark 使用“computeStats”方法抽象出各种 LogicalPlan 的统计信息。每个类都可以提供其对 computeStats 的实现。

如果代码我们可以看到 HiveTableRelation 类已覆盖此方法以返回表和列级别的统计信息(如果它们可用)。LogicalRelation类也做同样的事情。

在 HiveTableRelation 中:

  override def computeStats(conf: SQLConf): Statistics = {
    tableMeta.stats.map(_.toPlanStats(output)).getOrElse {
      throw new IllegalStateException("table stats must be specified.")
    }
  }

这反过来又调用 tableMeta.stats.map(_.toPlanStats(output))。

CatalogStatistics 中的代码:

  def toPlanStats(planOutput: Seq[Attribute]): Statistics = {
    val matched = planOutput.flatMap(a => colStats.get(a.name).map(a -> _))
    Statistics(sizeInBytes = sizeInBytes, rowCount = rowCount,
      attributeStats = AttributeMap(matched))
  }

这表明 Spark HiveTableRelation 也覆盖了computeStats方法,该方法返回所有表级别以及列级别的统计信息。因此,如果一个表生成了统计信息,CBO 将使用它们来优化计划。


推荐阅读