Snowflake 中的缓存如何工作

Snowflake 中的数据管道自动化

Emily Melhuish

Technical Curriculum Developer, Snowflake

三层缓存

缓存层.png

Snowflake 在三层进行结果缓存——作用范围与时长各不相同

  • 结果缓存——存完整查询结果;可在不启动仓库时直接返回
  • 仓库/数据缓存——近期扫描的微分区,存于内存与 SSD
  • 元数据缓存——始终开启;用于查询规划的表统计信息
Snowflake 中的数据管道自动化

何时使用结果缓存(及不使用时)

Snowflake 查询结果缓存流程图,展示查询向用户即时返回缓存结果

条件 何时为缓存未命中
查询文本完全匹配 大小写、空白或别名不同
无不可复用函数 运行间会变的函数:RANDOM
底层表未变 上次运行后发生 DML、重聚类或合并
持久化结果仍可用 24 小时 TTL 未复用而过期,或达 31 天
角色具备所需权限 SELECT:角色缺权限;SHOW:角色不同
Snowflake 中的数据管道自动化

仓库缓存与元数据缓存

Snowflake 数据缓存图,展示仓库缓存命中与未命中场景

仓库缓存

  • 将近期扫描的微分区存于仓库 SSD 与内存
  • 仓库挂起时清空
  • 适当延长自动挂起以保留缓存

元数据缓存

  • 始终开启,位于 Cloud Services
  • 存储表统计信息
  • 某些查询仅用元数据即可回答
Snowflake 中的数据管道自动化

阻止分区裁剪的 SQL 模式

阻止裁剪:

SELECT *
FROM logistics.shipments
WHERE MONTH(dispatch_date) = 3;

允许裁剪:

SELECT *
FROM logistics.shipments
WHERE dispatch_date >= '2024-03-01'
  AND dispatch_date <  '2024-04-01';
Snowflake 中的数据管道自动化

再避开两种 SQL 模式

避免 SELECT *

-- 读取所有列
SELECT * 
FROM logistics.shipments 
WHERE region = 'EMEA';

-- 只读所需列
SELECT shipment_id
, delivery_days 
FROM logistics.shipments 
WHERE region = 'EMEA';

避免隐式交叉连接

-- 缺少连接条件 = 笛卡尔积
SELECT s.shipment_id
, c.name 
FROM shipments s, carriers c;

-- 显式 JOIN 且带 ON 条件
SELECT s.shipment_id
, c.name 
FROM shipments s 
JOIN carriers c ON s.carrier_id = c.id;
Snowflake 中的数据管道自动化

开始练习吧!

Snowflake 中的数据管道自动化

Preparing Video For Download...