大家好我是小耶写功课只是为了我踩过的坑你们别再踩了写SQL写久了就会发现同样的业务需求不同的人写出来执行效率可能差几十倍。尤其是在复杂统计、排名分组这些场景选错写法查询能从毫秒级变成分钟级。以前做运营的时候我只需要看懂Excel里的公式转行后才明白SQL优化的本质是“用更少的扫描、更少的临时表完成同样的事”。今天就把子查询、CTE、窗口函数这三者的性能差异彻底讲透。这两年MySQL 8.0普及之后CTE和窗口函数不再是“新特性”而是每个写SQL的人必须掌握的技能。很多以前只能用子查询或临时表硬扛的需求现在有了更优雅高效的解法。理解这三种写法的性能特性能让你在面对复杂报表时少走弯路。先花一分钟搞懂三个概念​子查询​把一个查询的结果作为另一个查询的条件或数据源。优点是直观缺点是相关子查询外层每行执行一次内层性能极差。​**CTE公共表表达式**​可以理解为一个命名的临时结果集只在当前查询中有效。提升可读性还能支持递归查询比如组织架构树。​窗口函数​在保留原行数据的基础上对一组行进行聚合或排名计算。不会像GROUP BY那样压缩行数非常适合“每行后面加一个汇总值”的场景。实测对比每种写法最适合什么场景场景推荐写法原因简单过滤查某个用户的最新订单窗口函数 或 CTEJOIN一次扫描完成效率高多步复杂逻辑需要分步写CTE可读性最好便于调试每行后面跟一个汇总值窗口函数不改变行数一次扫描递归查询树形、BOM递归CTE唯一可行的标准写法EXISTS / IN半连接子查询优化器能处理好相关子查询改写成JOIN或窗口函数相关子查询通常较慢真实数据1000万行表查每个客户的最新订单环境MySQL 8.0.328C32G表orders有索引(order_date, customer_id)❌ ​相关子查询​耗时12.5秒SELECT * FROM orders o1 WHERE order_date (SELECT MAX(order_date) FROM orders o2 WHERE o2.customer_id o1.customer_id);✅ ​窗口函数​耗时3.8秒SELECT * FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date DESC) as rn FROM orders ) t WHERE rn 1;✅ ​CTEJOIN​耗时4.2秒WITH latest AS ( SELECT customer_id, MAX(order_date) as max_date FROM orders GROUP BY customer_id ) SELECT o.* FROM orders o JOIN latest l ON o.customer_id l.customer_id AND o.order_date l.max_date;结论相关子查询最慢窗口函数和CTEJOIN都在4秒左右。以后遇到“每组取最值”的需求优先用窗口函数。排名统计场景按部门计算员工工资排名10万行员工表按部门内工资排名。窗口函数RANK0.9秒代码一行SELECT *, RANK() OVER (PARTITION BY dept_id ORDER BY salary DESC) as rnk FROM emp;自连接旧写法7.2秒SQL复杂难懂SELECT e1.*, COUNT(DISTINCT e2.salary) as rnk FROM emp e1 LEFT JOIN emp e2 ON e1.dept_id e2.dept_id AND e1.salary e2.salary GROUP BY e1.id;窗口函数在排名、累计、移动平均等场景下性能和简洁度都是碾压级别。递归CTE实际运用查询组织架构树需求部门表dept(id, parent_id, name)查询id1及其所有下级。WITH RECURSIVE dept_tree AS ( SELECT id, parent_id, name FROM dept WHERE id 1 UNION ALL SELECT d.id, d.parent_id, d.name FROM dept d INNER JOIN dept_tree dt ON d.parent_id dt.id ) SELECT * FROM dept_tree;一次查询搞定这是MySQL 8.0之前很难优雅实现的。一点体会从运营转行做DBA之后我最深的感受是写SQL和做运营数据分析本质上都是“从数据里找答案”但SQL优化要求你更懂底层机制。窗口函数和CTE不是新语法它们是工具包里最趁手的两把扳手。遇到复杂统计第一反应应该是“能不能用窗口函数”而不是“先写个子查询凑合用”。掌握这三者不是为了炫技而是让查询跑得更快、代码更容易维护。小耶在手SQL 不愁还有什么想了解的欢迎留言小耶一定知无不言言无不尽……我们下次见~参考文献MySQL官方文档《Window Functions》《Common Table Expressions》《高性能MySQL》第4版第8章