Spark SQL表的基本统计估计

我知道我们可以在Spark SQL中显式ANALYZE表,这样我们可以获得一些准确的统计信息。

但是,Catalyst中可能存在一些不需要显式扫描整个表的实用程序,但是可以给我一些粗略的统计信息。我并不真正关心表的实际大小,只关心表之间的相对大小。因此,我可以使用此信息来确定在查询编译期间哪个表比其他表大。

Catalyst中有两个实用程序:

org.apache.spark.sql.catalyst.plans.logical.statsEstimation.{BasicStatsplanVisitor,SizeInBytesOnlyStatsplanVisitor}

但是看起来它们都需要显式扫描表。 谢谢。

lijipeng123 回答:Spark SQL表的基本统计估计

有两种方法,要么从metastore中获取统计信息,这需要事先运行ANALYZE(扫描数据),要么使用InMemoryFileIndex来估算统计信息(实际上只有SizeInBytes),不需要扫描数据,但使用Hadoop api Spark会收集每个文件的大小。

将使用哪种方法取决于更多设置。例如,如果SizeInBytes在metastore中可用,并且通过配置设置启用了CBO(基于成本的优化)

spark.cbo.enabled

,Spark将从元存储中获取它。如果CBO关闭(Spark 2.4中的默认值),Spark将使用InMemoryFileIndex。如果metastore中没有SizeInBytes,Spark仍然可以使用CatalogFileIndexInMemoryFileIndex。例如,如果您的表已分区,将使用CatalogFileIndex,更具体地说,如果满足此条件(直接从Spark源代码获取):

val useCatalogFileIndex = sparkSession.sqlContext.conf.manageFilesourcePartitions && catalogTable.isDefined && catalogTable.get.tracksPartitionsInCatalog && catalogTable.get.partitionColumnNames.nonEmpty

在这种情况下,如果统计信息不在metastore中,Spark将通过配置设置使用defaultSizeInBytes

spark.sql.defaultSizeInBytes

,默认情况下为Long.MaxValue,因此大小将被高估到最大值。我猜这是最糟糕的情况,统计信息不在metastore中,但是Spark正在使用CatalogFileIndex在那里寻找它们,找不到它,因此使用了非常大的不切实际的值。

本文链接:https://www.f2er.com/3148324.html

大家都在问