Spark SQL CACHE TABLE 详解一、语法-- 1. 缓存已存在的表/视图CACHETABLEtable_name;-- 2. 缓存查询结果为临时表CACHETABLEtable_nameASSELECT...;-- 3. 懒加载首次查询时才缓存CACHE LAZYTABLEtable_nameASSELECT...;二、缓存原理┌─────────────────────────────────────────────────────────┐ │ SparkSession │ │ ┌─────────────────────────────────────────────────┐ │ │ │ CacheManager │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ │ │ Table A │ │ Table B │ │ Table C │ │ │ │ │ │ (缓存) │ │ (缓存) │ │ (缓存) │ │ │ │ │ └─────────┘ └─────────┘ └─────────┘ │ │ │ └─────────────────────────────────────────────────┘ │ │ ↓ │ │ ┌─────────────────────────────────────────────────┐ │ │ │ Executor 内存 │ │ │ │ BlockManager (实际存储缓存数据) │ │ │ └─────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────┘缓存流程执行查询生成 DataFrame将 DataFrame 注册到 Session 的 CacheManager触发 Action非 LAZY 模式立即触发将数据缓存到 Executor 内存三、缓存级别级别说明适用场景MEMORY_ONLY仅内存内存不足时分区丢失小数据集内存充足MEMORY_AND_DISK内存优先不足时溢写到磁盘Spark SQL 默认通用场景DISK_ONLY仅磁盘大数据集内存紧张MEMORY_ONLY_SER内存序列化节省空间内存紧张但 CPU 有余OFF_HEAP堆外内存需避免 GC 影响SQL 限制CACHE TABLE默认MEMORY_AND_DISK不可自定义。DataFrame API 可自定义df.persist(StorageLevel.MEMORY_ONLY)四、LAZY vs 非 LAZY-- 非懒加载立即执行查询并缓存CACHETABLEtmpASSELECT*FROMbig_tableWHEREdt2026-07-01;-- ↑ 执行计划立即触发数据加载到内存-- 懒加载仅记录缓存意向首次查询时才缓存CACHE LAZYTABLEtmpASSELECT*FROMbig_tableWHEREdt2026-07-01;-- ↑ 此时什么都不做SELECT*FROMtmp;-- 这里才真正缓存选择建议确定会用 →CACHE TABLE立即加载可能不用 →CACHE LAZY TABLE按需加载五、作用域与生命周期┌────────────────────────────────────────────────┐ │ Spark Application │ │ ┌──────────────┐ ┌──────────────┐ │ │ │ Session A │ │ Session B │ │ │ │ ┌──────────┐ │ │ ┌──────────┐ │ │ │ │ │ cache_t1 │ │ │ │ cache_t1 │ │ │ │ │ │ (独立) │ │ │ │ (独立) │ │ │ │ │ └──────────┘ │ │ └──────────┘ │ │ │ └──────────────┘ └──────────────┘ │ │ ↓ ↓ │ │ Session 关闭 Session 关闭 │ │ 缓存自动释放 缓存自动释放 │ └────────────────────────────────────────────────┘特性说明作用域Session 级别不同 Session 隔离生命周期Session 存活期间有效释放时机Session 关闭 / UNCACHE TABLE / CLEAR CACHE跨 Session不共享同名表互不影响六、常用操作-- 1. 缓存表CACHETABLEtmpASSELECTwaybill_code,status,update_timeFROMapp.test;-- 2. 查看缓存状态DESCRIBEEXTENDEDtmp;-- 输出中查找: Is Cached: true-- 3. 解除单个缓存UNCACHETABLEtmp;-- 4. 清除所有缓存CLEAR CACHE;七、实际应用场景场景1维表重复关联-- 小维表被多次关联缓存避免重复扫描CACHETABLEdim_region;CACHETABLEdim_status;SELECTa.*,r.region_name,s.status_nameFROMfact_order aJOINdim_region rONa.region_idr.idJOINdim_status sONa.statuss.code;SELECTa.*,r.region_nameFROMfact_order_detail aJOINdim_region rONa.region_idr.id;场景2中间结果复用-- 中间结果被多次引用CACHETABLEtmp_filteredASSELECT*FROMbig_tableWHEREdt2026-07-01ANDstatusIN(1,31);-- 后续多次查询直接走内存SELECTCOUNT(*)FROMtmp_filteredWHEREstatus1;SELECTCOUNT(*)FROMtmp_filteredWHEREstatus31;SELECTwaybill_codeFROMtmp_filteredLIMIT100;场景3迭代计算-- 机器学习/图计算迭代场景CACHETABLEgraph_nodesASSELECT*FROMnodes;-- 多轮迭代读取同一份数据-- 第1轮SELECT/* BROADCAST(graph_nodes) */...FROMgraph_nodes;-- 第2轮SELECT/* BROADCAST(graph_nodes) */...FROMgraph_nodes;八、注意事项问题说明解决方案内存溢出缓存过多导致 OOM控制缓存数据量及时 UNCACHE数据过期源表更新后缓存未刷新手动 UNCACHE 后重新 CACHE占用 Executor 内存影响其他任务执行评估内存容量选择合适数据集小文件问题缓存表有小文件缓存前 REPARTITION重复缓存同一表多次 CACHE 无效Spark 会检查是否已缓存九、性能调优建议-- 1. 缓存前优化文件数CACHETABLEtmpASSELECT/* REPARTITION(100) */*FROMbig_table;-- 2. 只缓存需要的列CACHETABLEtmpASSELECTcol1,col2,col3FROMbig_table;-- 不要 SELECT *-- 3. 及时释放UNCACHETABLEtmp;-- 用完及时释放十、与 Hive Metastore 的区别对比项CACHE TABLECREATE TABLE存储位置Executor 内存HDFS/S3作用域Session 级别全局Metastore持久性Session 结束即消失永久保存跨 Session不可见所有 Session 可见同名冲突不同 Session 不冲突全局冲突十一、总结CACHE TABLE 内存缓存 Session 隔离默认级别 MEMORY_AND_DISK适用场景 维表关联、中间结果复用、迭代计算核心原则 够用即可用完释放