FlinkSQL Joins全解析
1. Lookup Join
用途:用于流表与外部维表(静态或缓慢变化表)的关联(如 MySQL、HBase 等)。
特点:
通过 实时查询外部存储 获取维度数据。
仅支持 处理时间(Processing Time)语义,无法关联历史版本。
结果会随维表数据更新而变化(如维表更新,后续关联结果可能不同)。
示例:
sql
SELECT o.order_id, o.user_id, u.user_name FROM Orders AS o JOIN Users FOR SYSTEM_TIME AS OF o.proc_time AS u ON o.user_id = u.user_id;
2. Regular Join(流式无限 Join)
用途:两条流的普通 Join,无时间约束,匹配所有历史数据。
特点:
输出结果会持续更新(可能因迟到数据反复触发)。
需要保留双流完整状态(可能导致状态无限增长)。
支持 事件时间(Event Time)和处理时间。
适用场景:需要精确匹配所有历史数据的场景(如用户行为链路分析)。
风险:状态管理复杂,需设置 TTL 避免 OOM。
3. Interval Join(时间区间 Join)
用途:两条流在特定时间范围内的 Join。
特点:
通过 时间区间约束(如
BETWEEN lower_bound AND upper_bound
)限制状态保留量。仅输出时间范围内匹配的数据,状态自动清理。
支持 事件时间和处理时间。
示例:
sql
SELECT o.order_id, s.shipment_id FROM Orders o JOIN Shipments s ON o.order_id = s.order_id AND s.ship_time BETWEEN o.order_time - INTERVAL '1' HOUR AND o.order_time + INTERVAL '1' HOUR;
4. Temporal Table Join(时态表 Join)
用途:关联 版本化表(如带版本信息的维表)。
特点:
支持 事件时间语义,可关联维表的历史版本。
维表需定义时间属性字段(如版本时间或生效时间)。
与 Lookup Join 的区别:Lookup Join 查最新数据,Temporal Join 按时间戳匹配历史版本。
示例:
sql
SELECT o.order_id, r.currency_rate FROM Orders o JOIN Rates FOR SYSTEM_TIME AS OF o.order_time AS r ON o.currency = r.currency;
5. Window Join(窗口 Join)
用途:在 窗口(如滚动、滑动、会话窗口) 内关联两条流。
特点:
输出窗口结束时触发计算,仅输出一次结果(不更新)。
状态按窗口自动清理。
支持 事件时间和处理时间。
示例:
sql
SELECT a.user_id, COUNT(b.order_id) FROM UserActions a JOIN Orders b ON a.user_id = b.user_id AND TUMBLE(a.event_time, INTERVAL '5' MINUTE) = TUMBLE(b.order_time, INTERVAL '5' MINUTE) GROUP BY a.user_id, TUMBLE(a.event_time, INTERVAL '5' MINUTE);
区别与联系总结
Join 类型 | 输入类型 | 时间约束 | 状态管理 | 适用场景 |
---|---|---|---|---|
Lookup Join | 流 + 外部表 | 处理时间 | 无状态 | 实时维表查询(如 MySQL 数据) |
Regular Join | 流 + 流 | 无约束 | 无限状态(需 TTL) | 精确历史匹配(风险高) |
Interval Join | 流 + 流 | 相对时间区间 | 按区间清理 | 有时间范围的流关联(如订单物流) |
Temporal Join | 流 + 版本化表 | 事件时间 | 按版本保留 | 关联维表历史版本(如汇率变化) |
Window Join | 流 + 流 | 窗口绝对时间 | 按窗口清理 | 窗口聚合统计(如 5 分钟订单行为) |
如何选择?
需要外部维表 → Lookup Join(最新数据)或 Temporal Join(历史版本)。
无时间约束的流流 Join → Regular Join(慎用,需 TTL)。
有时间范围的流流 Join → Interval Join 或 Window Join。
窗口聚合 → Window Join。
通过合理选择 Join 类型,可平衡计算延迟、状态管理和业务需求。