Skip to main content

FlinkSQL性能优化

Flink SQL 性能优化全攻略:从聚合到去重,这些技巧你必须知道!

无论是处理高吞吐数据还是解决热点问题,Flink SQL 的优化技巧都能让你的作业性能大幅提升!今天为大家整理了一份 超全优化指南,涵盖 Group Aggregate、TopN、高效去重、内置函数 等核心场景,快来收藏学习吧!


Group Aggregate 优化技巧

1️⃣ 开启 MiniBatch(提升吞吐)

  • 原理:微批处理减少 State 访问,提高吞吐量。
  • 适用场景:允许一定延迟,追求高吞吐的聚合场景。
  • 配置
    table.exec.mini-batch.enabled: true
    table.exec.mini-batch.allow-latency: 5s

2️⃣ 开启 LocalGlobal(解决数据热点)

  • 原理:分两阶段聚合(Local + Global),减少全局聚合压力。
  • 适用场景:SUM/COUNT/MAX/MIN/AVG 等普通聚合,需开启 MiniBatch。

3️⃣ 开启 PartialFinal(优化 COUNT DISTINCT)

  • 原理:自动打散 COUNT DISTINCT,缓解热点问题。
  • 配置
    table.optimizer.distinct-agg.split.enabled: true

4️⃣ AGG WITH FILTER 语法

  • 优化点:替代 CASE WHEN,减少 State 读写,性能提升 2 倍!
    -- 原始写法
    COUNT(distinct case when is_wireless='y' then visitor_id end) as UV2
    -- 优化写法
    COUNT(distinct visitor_id) FILTER (WHERE is_wireless='y') as UV2

TopN 优化技巧

1️⃣ 算法选择

  • 非更新流AppendRank
  • 更新流:优先 UpdateFastRank(需满足单调性条件)。

2️⃣ 无排名优化

  • 技巧:不输出 rownum,减少结果数据量。

3️⃣ 增加 Cache 大小

  • 配置
    table.exec.rank.topn-cache-size: 200000  -- 默认 10000

4️⃣ 关键字段

  • 确保 PARTITION BY 包含时间字段,避免 State TTL 导致数据错乱。

高效去重方案

1️⃣ 保留首行(Deduplicate Keep FirstRow)

SELECT * FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY b ORDER BY proctime) as rowNum
FROM T
) WHERE rowNum = 1

2️⃣ 保留末行(Deduplicate Keep LastRow)

SELECT * FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY b ORDER BY rowtime DESC) as rowNum
FROM T
) WHERE rowNum = 1

高效内置函数

  1. 优先使用内置函数:性能更优(如序列化优化)。
  2. KEY VALUE 函数:单字符分隔符(如 :)性能提升 30%。
  3. LIKE 操作
    • StartWith: LIKE 'xxx%'
    • EndWith: LIKE '%xxx'
  4. 慎用正则REGEXP 性能开销大,优先用 LIKE

SQL Hints 动态优化

通过提示(Hints)灵活控制执行计划,例如 Join 优化

-- 使用 BROADCAST 提示优化维表 JOIN
SELECT /*+ BROADCAST(dim) */ * FROM orders JOIN dim FOR SYSTEM_TIME AS OF orders.proctime ON orders.id = dim.id

总结

  • 聚合优化:MiniBatch + LocalGlobal + PartialFinal
  • TopN:算法选择 + Cache 调优
  • 去重:ROW_NUMBER 分首行/末行
  • 函数:内置优先,避免正则