MySQL优化子查询的实现示例

 更新时间:2025年09月24日 08:20:20   作者:软件求生  
本文主要介绍了MySQL子查询优化经验,指出子查询易因嵌套深、索引失效、临时表排序等问题导致性能问题,具有一定的参考价值,感兴趣的可以了解一下

大家好,我是小米,一个31岁还在互联网“搬砖”路上摸爬滚打的开发者。今天来和大家聊聊我最近经历的一场面试,主题是 “MySQL子查询优化”

说实话,这题目我一听见,心里咯噔了一下。因为子查询这东西,面试官一问,八成就是在等你掉坑。好在我这些年踩过的坑够多,顺手还能给大家写篇文章分享一下。

所以今天这篇文章,不仅仅是 面试题解析,更是 实战踩坑经验总结。如果你也正在准备社招面试,或者线上系统里SQL跑得慢得要死,这篇文章一定对你有帮助。

故事开场:面试官的“刁难”

面试官盯着我笑了一下,开口第一句就是:

“你觉得MySQL子查询该怎么优化?”

我脑子里立刻闪回起以前因为子查询写得不当,把线上数据库搞成蜗牛的场景。那次领导狠狠批评了我一句:

“小米啊,你这是在写SQL,还是在给数据库挖坟?”

我心里那个羞愧啊!后来我硬生生啃了几本MySQL优化的书,还在项目里做了好几次实战才算明白。

于是,我对面试官微微一笑:“子查询优化啊,我能聊一整天,要听完整版吗?”

为什么子查询经常会慢?

在进入优化方案之前,我们得先搞清楚: 子查询为什么容易拖垮性能?

常见问题有三:

1、嵌套太深

  • 内层子查询每次都要重新执行,数据量一大,效率直线下降。
  • 特别是 WHERE id IN (SELECT …) 这种写法,如果子查询没索引,简直噩梦。

2、不能充分利用索引

  • 子查询结果集经常需要临时表存放,而临时表往往没有合适的索引。

3、文件排序 & 临时表开销大

  • 一旦涉及 GROUP BY、DISTINCT、ORDER BY,MySQL可能会开临时表甚至文件排序,速度嗖嗖掉。

这就是为什么子查询看起来优雅简洁,但实际经常跑得像蜗牛。

优化方法一:用关联查询替代子查询

面试官最想听到的第一个答案就是这个:

“能不用子查询,就用JOIN代替。”

来看一个例子。

低效子查询写法:

这里的问题是:内层子查询可能会重复执行,效率低下。

改成关联查询:

这样做的好处:

  • 避免重复扫描:JOIN会直接利用索引做匹配。
  • 优化器更聪明:JOIN查询可以用到更优的执行计划,比如索引合并、驱动表选择等。
  • 结果集更可控:方便加条件、加排序,而不是靠子查询临时表。

面试小技巧:当面试官追问时,你可以补充一句:

“如果student.id是主键,JOIN的效率会比IN快很多,尤其是大表查询。”

这句话一出口,面试官眼睛一定会亮一下。

优化方法二:优化GROUP BY和DISTINCT

面试时,面试官继续追问我:

“那GROUP BY和DISTINCT呢?它们是不是也会拖慢速度?”

我立刻想到了之前的惨痛经历。那时候我写了一个统计SQL:

结果线上跑了半天,CPU打满。后来我才知道:

  • MySQL执行 GROUP BY 时默认会排序。
  • 如果数据量大,没索引,那就是灾难。

优化方案:

1、利用索引

  • 给 student_id 建索引,MySQL能直接利用索引分组,大幅加速。

2、用DISTINCT时同理

  • SELECT DISTINCT student_id FROM score;
  • 如果有索引,DISTINCT直接走索引去重,效率嗖嗖的。

3、GROUP BY + ORDER BY NULL

  • 如果你不关心结果的顺序,可以这样写:

  • ORDER BY NULL 告诉MySQL:别再排序了,直接分组结果就行。这样能避免文件排序,大幅提速。

优化方法三:关联查询中,使用标识列分组更高效

假设我们有学生表和成绩表,需要统计每个学生选课数。

原始写法:

这里用 s.name 分组其实很低效,因为 name 不是主键,还可能存在重复或者长字符串比较。

优化写法:

理由很简单:

  • 主键/标识列更容易利用索引。
  • 字符串分组开销大,而数字分组快如闪电。

小米碎碎念:这一点,面试官经常会用来考察候选人是否理解“索引对分组的影响”。

优化方法四:WITH ROLLUP要慎用

有些小伙伴喜欢用 WITH ROLLUP 做超级聚合,比如统计成绩时自动加总:

虽然语法很酷,但问题是:

  • ROLLUP 计算量大,容易让查询变慢。
  • 有些逻辑其实在应用层做更灵活,比如用Java/Go/Python聚合。

所以,面试官要是问到这里,我一般会说:

“在数据量不大时,ROLLUP很方便。但如果是大数据量场景,建议把超级聚合逻辑挪到应用程序处理,数据库只负责最基本的统计。”

这句话能让你显得思路全面,不死抠SQL,而是懂得架构层面取舍。

实战经验:子查询优化的黄金四步

我总结了一套面试时特别好用的“四步口诀”,分享给大家:

  • 能JOIN就不用子查询:特别是 IN (SELECT …),替换成JOIN几乎必快。
  • GROUP BY/DISTINCT走索引:一定要确认字段有索引,不然就是全表扫描。
  • 分组列优先用主键或整型标识列:避免用字符串或复杂字段做分组。
  • ORDER BY NULL + 应用层聚合:不需要排序时,果断加 ORDER BY NULL;超级聚合挪到应用层。

只要这四步背下来,面试官再怎么追问,你都能侃侃而谈。

小米的踩坑瞬间

最后分享一个让我刻骨铭心的场景。那是我入职某电商平台的第一周,老板让我写个统计SQL:

结果跑了10分钟还没出来,老板差点以为我不会写SQL。后来我改成:

0.8秒出结果!老板看完还夸我一句:“小米,干得漂亮。”

从那以后,我就彻底记住了:

子查询能不用就别用,优化就是钱。”

结语

如果你在面试中被问到“如何优化子查询?”,千万别慌。按照我上面分享的思路来:

  • 先说子查询的缺点(执行慢、索引利用率低、容易临时表)。
  • 再一条条抛出优化思路(JOIN替代、GROUP BY优化、标识列分组、ORDER BY NULL、ROLLUP挪应用层)。
  • 最后补充一点自己的实战经验。

这样下来,不仅能显得你技术扎实,还能让面试官觉得你是“踩过坑、能解决问题”的人。

毕竟,面试官要找的不是会背八股的人,而是能把问题搞定的工程师。

END

到此这篇关于MySQL优化子查询的实现示例的文章就介绍到这了,更多相关MySQL优化子查询内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MySQL查询截取的深入分析

    MySQL查询截取的深入分析

    这篇文章主要给大家介绍了关于MySQL查询截取的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • select into from和insert into select的区别举例详解

    select into from和insert into select的区别举例详解

    这篇文章主要介绍了SQL中的SELECT INTO和INSERT INTO SELECT两种语句的区别和用法,SELECT INTO用于创建新表并复制数据到新表中,而INSERT INTO SELECT用于将数据从一个表插入到已存在的另一个表中,需要的朋友可以参考下
    2025-03-03
  • MySQL 聚簇索引、非聚簇索引与回表详解

    MySQL 聚簇索引、非聚簇索引与回表详解

    本文我们从数据库物理存储的底层逻辑出发,系统拆解了聚簇索引与非聚簇索引的核心概念、存储结构、查询流程,以及"回表"操作的本质,感兴趣的朋友跟随小编一起看看吧
    2026-02-02
  • MySQL 查询重复数据的具体示例

    MySQL 查询重复数据的具体示例

    本文介绍MySQL查询重复数据的三种方法分别是通过GROUP BY和HAVING查找重复记录,使用子查询或JOIN列出所有重复行,添加计数显示重复次数,同时提醒注意性能优化与数据备份,对mysql查询重复数据相关知识感兴趣的朋友一起看看吧
    2025-07-07
  • mysql8中如何设置sql-mode

    mysql8中如何设置sql-mode

    这篇文章主要介绍了mysql8中如何设置sql-mode问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • 老生常谈mysql event事件调度器(必看篇)

    老生常谈mysql event事件调度器(必看篇)

    下面小编就为大家带来一篇老生常谈mysql event事件调度器(必看篇)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • 浅谈innodb的索引页结构,插入缓冲,自适应哈希索引

    浅谈innodb的索引页结构,插入缓冲,自适应哈希索引

    下面小编就为大家带来一篇浅谈innodb的索引页结构,插入缓冲,自适应哈希索引。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • 全面解读MySQL主从复制,从原理到安装配置

    全面解读MySQL主从复制,从原理到安装配置

    这篇文章主要介绍了MySQL主从复制的相关资料,帮助大家更好的理解和使用MySQL,感兴趣的朋友可以了解下
    2020-08-08
  • mysql性能优化脚本mysqltuner.pl使用介绍

    mysql性能优化脚本mysqltuner.pl使用介绍

    无意中发现了,major哥们开发的一个性能分析脚本,很有意思,可以通过这个脚本学学他的思想
    2013-02-02
  • 用Autoconf检测MySQL软件包的教程

    用Autoconf检测MySQL软件包的教程

    这篇文章主要介绍了用Autoconf检测MySQL软件包的教程,主要使用编写好的ax_lib_mysql脚本进行操作,需要的朋友可以参考下
    2015-06-06

最新评论