首页 > 解决方案 > Hive 内部表和 SparkSql 中的分桶

问题描述

我通过数据帧编写器 saveAsTable api 创建了一个分桶的内部配置单元表。

df.repartition(numBuckets, somecol)
              .write()
              .format("parquet")
              .bucketBy(numBuckets,col1)
              .sortBy(col1)
              .saveAsTable(hiveTableName);

现在我通过 spark sql 触发 2 个选择查询,一个在分桶列上,另一个在非分桶列上,但我看不到执行时间有任何差异。

查询是: select * from t1 where col1='123' [t1 is bucketed by col1] select * from t1 where col2='123' [col2 is not a bucketing column] 我的问题是

  1. 我如何确定在查询执行期间正在发生全表扫描或相关的部分表扫描正在发生?
  2. 我可以从 DAG 或物理计划中获得任何信息吗?两者我都看过,但我看不出有什么区别 这是我在物理计划中看到的

    == 物理计划 == *(1) 项目 [col1#0, col2#1, col3#2, col4#3, col5#4, col6#5, col7#6, col8#7, col9#8, col10# 9, col11#10, col12#11] +- *(1) 过滤器 (isnotnull(col2#1) && (col2#1 = 123)) +- *(1) FileScan parquet default.uk_geocrosswalk[col1#0,col2 #1,col3#2,col4#3,col5#4,col6#5,col7#6,col8#7,col9#8,LSOA_MSOA_WEIGHT#9,col11#10,col12#11] 批处理:true,格式:Parquet , 位置: InMemoryFileIndex[hdfs://url/a.parquet, PartitionFilters: [], PushedFilters: [IsNotNull(col2), EqualTo(col2,123)], ReadSchema: struct

  3. 在物理计划中为什么要进行文件扫描?由于表已创建为配置单元表,因此不应该执行 HiveTableScan 吗?

  4. 在使用 sparksql 时,是否有某些配置参数可以用来调整我的查询?
  5. 我看到每次我在 spark sql 中第一次运行查询都需要相当长的时间。有没有办法可以在执行查询之前预热执行程序?

标签: apache-sparkhiveapache-spark-sql

解决方案


镶木地板是柱状的。根据我的经验,镶木地板非常快。柱状方面可以很好地解释相同的性能 - 无论是否键,数据格式在物理上都是柱状的。

这是一个 Hive 表,但使用 Parquet 和 Bucketing,Hive / Impala 无法访问。由于是 Parquet,Hive Table Scan 不合适。Hive 表可以有多种物理格式,文本、Parquet、ORC。

可以看到过滤:PartitionFilters: [], PushedFilters: [IsNotNull(col2), EqualTo(col2,123)],

没有这样的热身。您可以 .cache 东西,但我已经测试并看到了在缓存 Parquet 表方面没有太大差异的测试,但这取决于测试。


推荐阅读