LAG本身不检测突增,仅计算相邻行差值;可靠检测需先时间对齐、再滚动聚合基线,或用统计模型如AnomalyDetection_SpikeAndDip。

用 LAG 检测突增是否靠谱?
LAG 本身不检测峰值,它只取上一行值——误以为 LAG 能直接识别“突增”,是常见误解。比如写 WHERE value - LAG(value) > 100,看似在找跳变,实则依赖严格有序、等间隔、无缺失的时间序列。真实数据流里,设备掉线、乱序写入、批量补传都会让 LAG 返回错误参照值,导致漏报或误报。
真正能稳住的,是先对时间戳做显式排序 + 窗口对齐,再用 LAG 做差值比较。但即使这样,它也只能识别“单点跃升”,无法区分临时毛刺和持续性峰值。
突发峰值 ≠ 单点跳变,得看窗口内统计趋势
业务关心的“突发”往往是:某指标在连续 N 秒/分钟内显著高于基线。这需要滚动聚合,不是行间差值。
-
LAG只能对比相邻行,无法表达“过去5分钟均值” - 正确做法是配合
AVG() OVER (ORDER BY ts ROWS BETWEEN 299 PRECEDING AND CURRENT ROW)计算滑动基线 - 再用当前值除以该基线,设阈值(如 > 2.5)判定为突发;避免用固定差值,因量纲不同(QPS、字节数、延迟毫秒)不可比
- MySQL 8.0+、PostgreSQL、SQL Server 2016+ 支持标准窗口函数;旧版 SQL Server 需用 CTE + 自连接模拟,性能差一到两个数量级
游标类峰值检测(如 AnomalyDetection_SpikeAndDip)和 LAG 的本质区别
像 Azure Stream Analytics 的 AnomalyDetection_SpikeAndDip 是基于统计模型(Robust Z-Score + 季节性滤波),而 LAG 是纯确定性位移操作。两者不在同一抽象层:
-
LAG不建模、不拟合、不适应噪声——它只是取数,你得自己加逻辑判断 -
AnomalyDetection_SpikeAndDip内部会动态估算局部方差、剔除历史异常点、容忍一定乱序,但要求输入是均匀采样(非均匀需先GROUP BY TUMBLINGWINDOW聚合) - 若用 SQL 自实现类似效果,至少要组合:
PERCENTILE_CONT估算中位数、STDDEV算离散度、再套三层嵌套子查询——可读性和维护性急剧下降
什么时候硬用 LAG 反而更稳妥?
当你的场景满足三个硬条件时,LAG 反而是最轻、最快、最可控的选择:
- 数据已按时间严格升序且无重复时间戳(例如日志采集端已做 dedup + sort)
- “突发”定义明确为“相比前一条记录增长超 X%”,不涉及周期性或上下文基线
- 数据量大但 QPS 低(如每秒几条传感器心跳),不需要亚秒级响应,也不需回填修正
- 注意:MySQL 中
LAG在未指定PARTITION BY时会跨分组污染结果,务必检查是否漏写了设备 ID 或会话 ID 分组
复杂点在于,真实流数据几乎从不满足“严格升序无重复”——所以多数情况下,别省那一步 ROW_NUMBER() + self-join 或 TIME_BUCKET 对齐,该花的开销省不掉。










