apache-spark - 优化多次使用的表:使数据框持久化或另存为镶木地板
问题描述
我听说 Spark SQL 很懒惰:每当引用结果表时,Spark 都会重新计算该表 :(
例如,
WITH tab0 AS (
-- some complicated SQL that generates a table
-- with size of Giga bytes or Tera bytes
),
tab1 AS (
-- use tab0
),
tab2 AS (
-- use tab0
),
...
tabn AS (
-- use tab0
),
select * from tab1
join tab2 on ...
...
join tabn on ...
...
Spark 可以重新计算 tab0 N 次。
为避免这种情况,可以将 tab0 保存为临时表。我找到了两个解决方案。
1)将tab0保存到镶木地板中,然后将其加载到临时视图中
https://community.hortonworks.com/articles/21303/write-read-parquet-file-in-spark.html createOrReplaceTempView 如何在 Spark 中工作?
2) 使 tab0 持久化
https://spark.apache.org/docs/2.2.0/rdd-programming-guide.html#rdd-persistence
就查询速度而言,哪一个更好?
解决方案
如果您有足够的内存来保存数据,使用dataFrame.cache()
将比作为 Parquet 写入磁盘并使用 TempView 访问它要快。TempView 可能会进入磁盘 N 次。
如果您没有足够的内存,我会进行基准测试,看看在 MEMORY_AND_DISK 存储级别和写入 Parquet 之间是否存在差异。我很难想象 Spark 使用的磁盘格式会比Parquet 效率低(因为在这种情况下为什么不直接使用 Parquet?),但我学会了在优化 Spark 代码时要小心我的假设。
推荐阅读
- javascript - ASP.NET Core Ajax 文件并行上传导致服务器两次返回相同的结果
- node.js - 为什么 Grafana 在不同范围内为计数器指标返回不同的值
- ruby-on-rails - 同一字段中的多词 Ransack 搜索不起作用
- embedded - 使用命令行使用 GHS 探针闪烁目标
- eclipse-rcp - e4 RCP 应用程序:如何禁用与对话框的窗口交互?
- ibm-cloud - IBM Cloud COS:使用 S3 API get-bucket-location 返回未找到存储桶
- typo3 - FLUID 中的条件以检查列是否有内容
- ios - 获取IOS中的链接联系人列表
- angular - 将 Angular 7 应用程序部署到 Azure Web 应用程序
- apache-kafka - KSQL/Kafka Streams 可以支持复杂的事件处理吗?