You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何截断表后Cached DataFrame被清空?缓存机制疑问

问题:为什么缓存后的DataFrame在truncate表后显示为空?

先看你执行的操作步骤:

scala> val df = sql("select * from table")
df: org.apache.spark.sql.DataFrame = [num: int]

scala> df.cache
res13: df.type = [num: int]

scala> df.collect
res14: Array[org.apache.spark.sql.Row] = Array([10], [10])

scala> df.show
+---+
|num|
+---+
| 10|
| 10|
+---+

scala> sql("truncate table table")
res17: org.apache.spark.sql.DataFrame = []

scala> df.show
+---+
|num|
+---+
+---+

你的疑问是:既然df已经被缓存到内存,执行truncate table后应该还能看到缓存的数据,但实际却显示为空,这是为什么?

原因解析

这其实是Spark的默认保护行为:当你执行DDL操作(比如TRUNCATE、DROP、ALTER TABLE这类修改表结构或底层数据的语句)时,Spark会自动清除所有依赖于该表的缓存数据。

具体过程是这样的:

  1. 你调用df.cache()并执行df.collect()时,确实已经把df的计算结果缓存到了内存中。
  2. 但当你执行sql("truncate table table")这个DDL操作时,Spark会检测到该操作修改了原表的数据——为了避免后续查询返回过期的缓存数据,它会自动清除所有与这个表绑定的缓存(包括你之前缓存的df)。
  3. 所以当你再次调用df.show()时,缓存已经不存在了,Spark只能重新执行select * from table的查询,而此时原表已经被清空,自然返回空结果。

如果你希望在truncate表后依然能访问缓存的数据,可以试试这两个办法:

  • 直接使用collect()返回的本地数组(比如把val data = df.collect()保存下来),后续直接操作这个本地集合,不再依赖DataFrame的缓存。
  • 在执行DDL操作之前,将DataFrame的数据写入到另一个持久化存储(比如临时表、Parquet文件等),之后从这个新存储读取数据。

内容的提问来源于stack exchange,提问作者Tomasz Krol

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:01:38