最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
为何大数据场景下SQL窗口函数比子查询更节省内存
时间:2026-06-18 08:58:47 编辑:袖梨 来源:一聚教程网
窗口函数比子查询更高效,因其仅需一次排序和一次线性遍历,在内存中构建并复用窗口框架;而子查询每行都重复建临时表、反复排序,导致O(N²)复杂度与内存峰值线性增长。
窗口函数只建一次临时结构,子查询每行都新建
窗口函数的 Using temporary 是构建内存中的窗口框架,整张表的数据只进这个结构一次;而关联子查询在 DEPENDENT SUBQUERY 模式下,每处理外层一行,就重新分配一块临时空间、重建筛选条件、再扫描内表——10 万行外层数据,就可能触发 10 万次临时结构创建。MySQL 不会复用这些临时结构,内存峰值直接线性翻倍。
排序只做一遍,子查询反复排序
窗口函数的 Using filesort 发生在初始化阶段:按 PARTITION BY + ORDER BY 一次性排序,后续所有窗口计算都基于这个已排序流滑动执行;子查询里如果带 ORDER BY 或隐含排序(比如 MAX() 配合 WHERE),每次执行都要重排——没索引时,就是 N 次磁盘排序,内存缓冲区反复被冲刷。
- 有复合索引
(department, salary DESC)时,窗口函数可跳过排序,子查询仍需为每组单独判断是否走索引 -
LAG()、LEAD()这类函数依赖排序定义“前一行”,没ORDER BY就退化为随机行,但子查询无法规避该逻辑开销
数据不落盘,子查询容易触发磁盘临时表
窗口函数全程在 sort_buffer 和 window_frame 内存区域中流式计算,只要总数据量不超过 sort_buffer_size 和 read_rnd_buffer_size 之和,就不会写磁盘;子查询单次结果集稍大(比如部门平均薪资涉及几百人),或内存不足时,就会生成磁盘临时表——这不仅吃内存,还引入 I/O 延迟和锁竞争。
- MySQL 默认
tmp_table_size和max_heap_table_size通常为 64MB,超限即落盘 - 子查询的
loops值在EXPLAIN ANALYZE中等于外层行数,是内存压力最直接的指标
聚合状态共享,子查询各自维护上下文
SUM() OVER (PARTITION BY user_id ORDER BY order_time) 在内存中维护一个滑动累加器,同一用户的数据连续到达时,只需加减当前值;子查询如 (SELECT SUM(amount) FROM orders o2 WHERE o2.user_id = o1.user_id) 每次都要从头扫描、过滤、累加,无法复用前序计算结果,CPU 和内存带宽都被重复消耗。
真正容易被忽略的是:窗口函数的内存节省不是靠“少算”,而是靠“不重复建上下文”——一旦你看到执行计划里 Using filesort 和 Using temporary 同时出现且 loops=1,基本可以确认这是最优路径;若子查询的 loops 显著大于 1,内存压力已经实打实地来了。
相关文章
- 战为王好玩吗 战为王玩法介绍 06-18
- 使命召唤21:黑色行动6: Black Ops 1 与 2 将在下月正式移植至新平台 06-18
- 讯飞星火是什么?AI认知大模型的能力与适用场景说明 06-18
- 6月17日在线修正——Abundance Naigtal 与 Lorewalking 06-18
- 美美小店第一章第四关 旅游达人s级攻略 06-18
- 洛克王国世界卷胡巨獭如何进化 06-18