如何将多临时表关联的统计SQL优化为单次扫描的查询语句?
现有实现的核心问题
- 对同一张
PlayerTrack表重复执行3次带GROUP BY的全量扫描,大表场景下IO开销极高,执行效率差 - 依赖多个临时表做INNER JOIN关联的写法存在逻辑漏洞:如果某支队伍的某个球衣号球员所有追踪帧都是插值生成的,那么在仅筛选非插值帧的Temp3表中不会存在对应行,INNER JOIN时会直接把该条数据过滤掉,导致最终统计结果缺漏
- 全流程需要创建4个临时表,额外占用临时存储空间,执行链路冗长
优化实现思路
用条件聚合逻辑,仅做1次表扫描就能完成所有维度的统计计算,完全不需要创建任何中间临时表,同时从逻辑上避免原写法丢数据的问题。
优化后的完整SQL如下:
SELECT TeamID, JerseyNumber, COUNT(FrameNumber) AS T, SUM(CASE WHEN Interpolated = 0 THEN 1 ELSE 0 END) AS NI, SUM(CASE WHEN Interpolated = 1 THEN 1 ELSE 0 END) AS I, -- 聚合阶段直接计算百分比,无需后续关联 (SUM(CASE WHEN Interpolated = 0 THEN 1 ELSE 0 END) * 1.0 / COUNT(FrameNumber)) * 100 AS NIPercentage, (SUM(CASE WHEN Interpolated = 1 THEN 1 ELSE 0 END) * 1.0 / COUNT(FrameNumber)) * 100 AS IPercentage FROM PlayerTrack GROUP BY TeamID, JerseyNumber;
可选的补充优化
- 可增加除零保护,避免极端场景下分母为0触发计算报错,把分母位置的
COUNT(FrameNumber)替换为NULLIF(COUNT(FrameNumber), 0)即可 - 如果表数据量较大,可在
(TeamID, JerseyNumber, Interpolated, FrameNumber)字段上建立覆盖索引,把全表扫描替换为索引扫描,进一步降低IO开销 - 优化后的写法完全保留了原逻辑中
COUNT(FrameNumber)只统计非空FrameNumber条目的统计口径,不会出现数据偏差
内容的提问来源于stack exchange,提问作者Bakeduck2021
相关产品推荐
相关产品推荐

