Flink SQL的窗口TVF和时间属性——新语法比旧语法好在哪?
先说结论
新项目全用窗口TVF语法。旧语法仍然可用但已不再新增功能。TVF支持更多语法(如窗口TopN、窗口Join),而且内部优化更好。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
Flink SQL的窗口语法经历了一次大升级:从旧的GROUP BY TUMBLE()语法升级到新的窗口TVF(Table-Valued Function)语法。新语法不仅更灵活,而且性能更好。如果你还在用旧语法,建议尽快升级。
旧语法 vs 新语法 对比
-- 旧语法(GROUP BY风格)
SELECT
country,
TUMBLE_START(event_time, INTERVAL '5' MINUTE) AS window_start,
COUNT(*) AS pv
FROM user_events
GROUP BY country, TUMBLE(event_time, INTERVAL '5' MINUTE);
-- 新语法(窗口TVF风格)
SELECT
country,
window_start,
window_end,
COUNT(*) AS pv
FROM TABLE(
TUMBLE(TABLE user_events, DESCRIPTOR(event_time), INTERVAL '5' MINUTES)
)
GROUP BY country, window_start, window_end;
TVF语法的三大优势
支持窗口TopN
旧语法无法直接在窗口结果上做TopN。TVF可以:
-- 每5分钟的PV Top3国家(只有TVF支持)
SELECT *
FROM (
SELECT country, window_start, pv,
ROW_NUMBER() OVER (PARTITION BY window_start ORDER BY pv DESC) AS rn
FROM (
SELECT country, window_start, COUNT(*) AS pv
FROM TABLE(
TUMBLE(TABLE user_events, DESCRIPTOR(event_time), INTERVAL '5' MINUTES)
)
GROUP BY country, window_start, window_end
)
)
WHERE rn <= 3;
支持窗口Join
可以把两个窗口聚合的结果Join起来,旧语法做不到。
更好的内部优化
TVF语法在Flink内部使用了更高效的执行计划,特别是在Cumulate窗口(累积窗口)场景下,性能比旧语法快很多。
Cumulate窗口(累积窗口,TVF独有)
这是TVF新增的窗口类型,旧语法没有。场景:“当天截止当前的累计GMV”,每分钟更新一次。
-- 当天累计GMV,每分钟更新
SELECT
window_start,
window_end,
SUM(amount) AS cumulative_gmv
FROM TABLE(
CUMULATE(
TABLE dwd_order_detail,
DESCRIPTOR(order_time),
INTERVAL '1' MINUTES, -- 每分钟更新
INTERVAL '1' DAY -- 最大窗口=一天
)
)
GROUP BY window_start, window_end;
这个场景以前要用滑动窗口实现,状态开销巨大。Cumulate窗口的状态开销小得多,因为它是在累加而不是重算。
总结
新项目全用窗口TVF语法。TVF的三大优势:支持窗口TopN、支持窗口Join、更好的内部优化。Cumulate窗口是TVF独有的实用功能。面试时能写出旧vs新语法的对比、说清楚TVF的独有优势,就很有深度。
最后一篇是最重要的综合题:请描述一个你用Flink做过的项目。
你们生产环境用的是旧语法还是TVF新语法?评论区聊聊~
关注「Wood聊大数据」| 9年大数据老兵,聊技术、聊职场、聊成长