SparkSQL中表与视图查询性能差异及表持久化问题问询
问题:Spark表持久化与跨Session访问问题
环境与初始现象
- 集群配置:5个工作节点(每节点8核、32GB内存),未关联Hive的Spark集群
- 初始现象:查询Spark表和临时视图时性能差异极大,后续排查发现是表创建过程中的数据加载异常,修正创建方式后两者性能一致
实验过程
(a) 初始创建表的代码
val df = spark.read.parquet(PATH) df.write.mode("overwrite").saveAsTable(xxx)
(b) 创建临时视图的代码
val df = spark.read.parquet(PATH) df.createOrReplaceTempView(xxx)
测试用例与性能表现
使用TPC-H scale=100数据集,执行查询Q17:
select avg(l_extendedprice) / 7.0 as avg_yearly from lineitem, part where p_partkey = l_partkey and p_brand = 'Brand#11' and p_container = 'SM CAN' and l_quantity < ( select 0.2 * avg(l_quantity) from lineitem where l_partkey = p_partkey);
- (a) 初始表生成耗时约3分钟,查询仅1秒完成,但后续执行
spark.sql("select * from table").show返回空表,确认是数据加载异常导致的虚假性能优势 - (b) 临时视图为延迟加载,总处理时间约50秒
物理计划差异
(a) 初始表的物理计划
(1) Scan parquet default.lineitem Output [3]: [l_partkey#26852L, l_quantity#26855, l_extendedprice#26856] Batched: true Location: InMemoryFileIndex [file:/xxx/spark-warehouse/lineitem] PushedFilters: [IsNotNull(l_partkey), IsNotNull(l_quantity)] ReadSchema: struct<l_partkey:bigint,l_quantity:double,l_extendedprice:double>
(b) 临时视图的物理计划
(1) Scan parquet Output [3]: [l_partkey#17L, l_quantity#20, l_extendedprice#21] Batched: true Location: InMemoryFileIndex [hdfs://master:9000/tpch100_parquet/lineitem] PushedFilters: [IsNotNull(l_partkey), IsNotNull(l_quantity)] ReadSchema: struct<l_partkey:bigint,l_quantity:double,l_extendedprice:double>
问题修正
调整表创建方式,显式指定HDFS存储路径后,表与视图的查询性能基本一致:
df.write.mode("overwrite").option("path","hdfs://master:9000/PATH/table_name").saveAsTable(x._1)
待解决问题
如何持久化已创建的表,使得重启Spark Session后可以直接访问?目前在spark-shell中能直接执行spark.sql(select * from former_table),但在spark-submit提交的任务中无法生效。
内容的提问来源于stack exchange,提问作者kqboy
相关产品推荐
相关产品推荐

