为什么同事写的SQL又快又清晰?揭秘子查询与CTE的终极对决!

B站影视 电影资讯 2025-09-08 21:23 1

摘要:早上开例会,隔壁组亮出执行计划,全表扫描次数从九次掉到一次,CPU直降八成。

同事一条SQL把30秒干成0.5秒,我却还在加班调索引

早上开例会,隔壁组亮出执行计划,全表扫描次数从九次掉到一次,CPU直降八成。

老板当场问:为啥你俩写同一张宽表,差距能顶一辆特斯拉?

答案藏在一个很小的选择:子查询还是CTE。

先看清规则。

子查询像快递袋,一次用完就扔;CTE像可折叠收纳箱,能反复打开再合起。

简单过滤,用子查询最省事。

逻辑一旦超过三层,CTE立刻把代码切成一段段能看懂的小块,后续复用不用再拼积木。

很多人卡在性能。

子查询会被优化器改写成JOIN,运气好就飞快;运气不好,同一段子查询被执行器重复跑几遍,磁盘狂转。

CTE默认会把结果先存进内存或临时文件,省得重复算,却可能撑爆缓存。

PostgreSQL 12以后多了WITH … AS … NOT MATERIALIZED,告诉数据库别急着落盘,能省一大笔I/O。

SQL Server用户更喜欢临时表加索引,大数据量分阶段处理也稳。

容易踩的坑有三。

NOT IN 碰见空值就全军覆没,换成NOT EXISTS立刻复活。

多层嵌套子查询有时让优化器放弃索引,直接扫全表。

几百万行的CTE一次性落盘,内存报警比群里红包还快,分批或加过滤条件就能缓和。

把视角拉远。

窗口函数叠加CTE,能把复杂排名、环比、同比写成三小段,运行照样快。

数据仓库里,把子查询结果写成物化视图,每天跑一次,报表直接读视图,高峰不再堵塞。

分布式数据库时代,CTE还能被拆成子任务并行跑,再合并结果,单机时代的瓶颈被平行计算直接抹平。

一条SQL值不值钱,就看读的人能不能三分钟看懂、三小时不改。

写之前先问自己:这段逻辑只出现一次,还是以后天天被同事抄?

答案清晰,选子查询还是CTE就不再纠结。

来源:古镇木雕赏精巧艺

相关推荐