订阅更新

Flink SQL的窗口TVF和时间属性——新语法比旧语法好在哪?

Flink手册 第 19 题 约 3 分钟读完

本文目录
  1. 先说结论
  2. 旧语法 vs 新语法 对比
  3. TVF语法的三大优势
  4. Cumulate窗口(累积窗口,TVF独有)
  5. 总结

先说结论

新项目全用窗口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年大数据老兵,聊技术、聊职场、聊成长

刷题进度保存在当前浏览器