大家好呀,我是你们的老朋友小米,31岁,依旧是个喜欢折腾技术的程序员。最近在帮一位朋友准备 MySQL 社招面试题时,碰到一个经典问题:"如何优化查询过程中的数据访问?"
听起来很朴素对吧?可真要聊透,里面可是门道多得很。今天我就给大家讲讲我和朋友的一次"面试题复盘",顺便分享一些我这些年踩过的坑。
故事的开头:查询慢得像蜗牛
朋友小A是互联网公司的后端工程师。前段时间他在写一个订单统计模块的时候,发现一个 SQL 慢得离谱。点开页面后,数据要好几秒钟才出来,用户都快以为系统挂了。
小A抓耳挠腮,心里嘀咕:
"这明明是个普通查询,怎么会这么慢?是不是服务器不给力?"
结果一看,MySQL CPU 飙高,磁盘 I/O 也在哭喊。其实问题不是服务器不给力,而是 访问数据太多。这就是我们今天要聊的第一个关键点。
访问数据太多导致性能下降
在 MySQL 优化里,有一个常见的坑:数据拿得太多。
就好比你去超市买瓶水,结果推了整整一车回家,当然费劲了。
具体表现有两种:
- 行太多:应用程序从数据库里拖了一大堆行出来,但其实只需要其中的一小部分。
- 列太多:表里有几十个字段,你只要其中两三个,但却全都查出来。
面试官可能会追问:那怎么判断呢?
我通常会让开发同事先看看 SQL,是不是 在检索大量超过需要的数据。如果是,那就是"搬水却背沙子"的典型情况。
确认 MySQL 服务器是否在分析不必要的数据行
很多人光看返回结果觉得没问题,但其实数据库在背后做了巨大的"无用功"。
比如有一次我帮团队排查慢查询,用 EXPLAIN 一看,才发现 MySQL 服务器扫描了几十万行,结果最后只返回了几十条。
这就是 分析了大量不必要的数据行。
记住一句话:不是看你拿了多少,而是看数据库干了多少。
几个常见的 SQL 错误
说到这里,小A的脸刷地红了。因为他的 SQL 正好犯了几个典型错误,我来替他"公开处刑"一下:
1、查询不需要的数据
- 错误:
------我只需要前 10 条,你却把所有的都拖了出来。
- 优化:
2、多表关联返回全部列
- 错误:
- 优化:
3、总是返回全部列
- 错误:动不动就 SELECT *,结果表一加字段,SQL 就崩了。
- 优化:只取你需要的字段,既省带宽,又提高缓存命中率。
4、重复查询相同的数据
- 错误:每次都跑去数据库捞数据。
- 优化:加缓存!Redis 或应用内缓存,下次直接读缓存,数据库轻松很多。
这四点,面试官基本都会考,因为它们是最常见的"坑点"。
是否在扫描额外的记录
那接下来问题来了:
就算你只查需要的列和行,为什么还是慢?
因为数据库可能 扫描了额外的记录。
这个时候,我们就要请出神器 ------ EXPLAIN。
EXPLAIN 就像显微镜,能让你看到 SQL 执行的内部逻辑:
- 它用到哪个索引?
- 扫描了多少行?
- 是全表扫描还是索引扫描?
如果发现 扫描几十万行,却只返回几十条,那就要想办法优化了。
优化扫描的几大技巧
优化扫描,常见的几招有:
1、索引覆盖扫描
- 如果所有查询的列都在索引里,那存储引擎就不用"回表",直接从索引里拿数据。
- 举个例子:
- ------这样查询就完全走索引,速度飞快。
2、改变数据库和表的结构
- 有时候索引怎么建都不行,根源在于表结构设计不合理。
- 这时候可能要考虑 范式化,把冗余数据拆出去,减少扫描量。
3、重写 SQL 语句
- 有些 SQL 写得拧巴,导致优化器没办法用好索引。
- 换个写法,优化器就能聪明地走索引了。
- 比如:
这样会导致索引失效。
- 优化写法:
面试对话:一场灵魂拷问
面试官: 如果查询太慢,你会怎么排查?
小A: 我会先看是不是拿的数据太多,比如行或列太多。
面试官: 然后呢?
小A: 我会用 EXPLAIN 看是不是扫描了太多无用的行,再考虑建索引、改表结构、或者重写 SQL。
面试官: 不错!那 SELECT * 为什么不推荐?
小A: 因为会增加数据访问量,还可能导致索引覆盖失效,缓存利用率低。
面试官: 很好,你可以去下一轮了。
是不是感觉逻辑很清晰?其实就是今天我们讲的那套思路。
总结:优化查询数据访问的心法
回顾一下今天的要点:
- 访问数据太多会拖慢性能,尤其是列和行过多。
- 确认是否在检索超过需要的数据。
- 检查 MySQL 是否分析了大量不必要的行。
- 避免常见错误:SELECT *、多表返回全部列、重复查询同一数据。
- 用 EXPLAIN 分析执行计划,看是否扫描了额外的记录。
- 解决思路:索引覆盖扫描、优化表结构、重写 SQL。
一句话总结:让数据库只做该做的事,别让它白干活。
END
数据库优化就像生活中的断舍离。别什么都往家里搬,也别把屋子弄得乱糟糟。查询要精准、简洁,数据库才会轻松。
希望今天的分享能帮你在面试中答得漂亮,也能在工作中少踩坑。
如果你也有遇到过奇葩的慢查询,欢迎留言一起讨论,说不定下次我们还能把你的案例写成故事哦~
我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号"软件求生",获取更多技术干货!