大家好呀,我是小米,今年31岁,一个热爱折腾代码、也喜欢和朋友们分享技术故事的程序员。
今天想和大家聊一个我在社招面试时常被问到的问题:
“你关心过业务系统里面的 SQL 耗时吗?统计过慢查询吗?对慢查询都怎么优化过?”
这道题其实不光是面试常客,也是每个开发在成长路上一定会遇到的“关卡”。毕竟,SQL写得漂不漂亮,决定了业务系统能不能跑得快,用户能不能用得爽。
那我就用一个故事,带你走进我和慢查询优化的那些经历。
业务系统里的“暗礁”——SQL 耗时
我第一次真正被 SQL 耗时“教育”,是在三年前。那时我们负责一个电商项目,流量突然暴增,页面加载慢到让我想摔键盘。运维同事找过来,甩了一份“慢查询统计”在我桌上,说:“哥们,你看看,你们业务 SQL 占了榜单前三。”
我当时就懵了。平时写 SQL,查个主键秒回,哪里想过会拖慢系统?可现实就是——
在业务系统里,除了主键查询,几乎所有 SQL 我都会在测试库上测一遍耗时,不然线上一旦炸了,代价惨痛。
所以后来我养成了一个习惯:只要不是特别简单的主键查询,我都会提前在测试库里跑一跑,看它的执行时间,顺便 explain 一下,心里有个底。
慢查询统计,幕后英雄
说实话,慢查询日志的统计主要还是运维在做。他们会定期把业务系统里的慢查询统计出来,整理成报告,反馈给我们。
这份“黑榜单”往往能让人瞬间清醒——因为有的 SQL 你以为没问题,结果在海量数据下就是个大坑。
我记得有一次,一个简单的 SELECT * FROM orders WHERE user_id = ?,居然在慢查询日志里反复出现。后来一看,发现 orders 表已经过亿行了,而 user_id 上居然没建索引!这就是典型的“想当然”操作。
慢查询统计,就像一面镜子,照出了我们代码里最真实的“伤疤”。
优化之前,先搞清楚“慢”的原因
很多同学一听到优化,就条件反射去加索引。其实这很容易走偏。
优化的第一步不是动手,而是搞明白:为什么慢?
我通常会从三个角度来分析:
- 查询条件没有命中索引?
- 比如 like '%xxx' 这种写法,索引压根用不上。
- SQL load 了不需要的数据列?
- 有些语句查了一大堆字段,但最后只用到一两个,等于做了无用功。
- 数据量太大?
- 这就算语句再完美,数据上亿也会拖慢查询。
每个方向背后都对应一套优化思路。
优化的“三板斧”
1. 语句分析与重写
我先会看看语句本身:
- 有没有查询多余的行?
- 有没有 select 了太多列?
- 有没有不必要的 join?
有一次我遇到一个特别经典的坑:
同事写了个查询,把所有用户的订单查出来,结果又在业务逻辑层丢掉 90% 的数据,只保留近一个月的。换句话说,SQL 白白 load 了几百万行数据,结果最后只要几千条。
重写 SQL 后,直接在 where 子句里加上时间条件,查询速度快了十倍不止。
2. 执行计划与索引优化
接下来我会用 EXPLAIN 看执行计划。它会告诉我:
- 用没用到索引?
- 用的是不是最优索引?
- 有没有全表扫描?
有一次我们遇到一个慢查询:
explain 一看,居然只用到了 city 索引,age 条件直接忽略了。原因是索引顺序设计不合理。后来我们建了一个联合索引 (city, age),性能立马飞起。
这让我意识到,优化 SQL,很多时候是和 DBA、运维一起“玩拼图”,找到 SQL 和索引之间的最佳契合点。
3. 分库分表,和数据量谈判
当语句优化、索引优化都到头了,那就得看数据量了。
如果一张表已经膨胀到上亿行,那查询再怎么优化,也难逃慢的宿命。这时候就要考虑:
- 横向分表:按时间、按用户 ID 做拆分。
- 纵向分表:把经常查询的核心字段放到主表,冷门字段放到扩展表。
我在一个日志系统里做过类似优化,把原来几十亿条的日志表,按月份分表。查询最新日志只查当月的表,速度嗖嗖的。
一个面试里的真实对话
我记得有次面试,面试官直接问我:
“你在业务系统里会关注 SQL 耗时吗?”
我回答:
“会的,除了主键查询,其他 SQL 我都会在测试库跑一遍,看耗时情况。”
他点点头,继续问:
“那慢查询统计谁来做?你们是怎么处理的?”
我说:
“慢查询日志由运维负责收集,他们会定期反馈,我们再逐一分析和优化。”
最后一个问题来了:
“你们怎么优化慢查询?”
我给了他“三板斧”:
- 分析 SQL,看是否查询了多余的数据行、列,能否重写。
- 用 explain 看执行计划,检查索引命中情况,调整语句或索引。
- 如果实在不行,就从数据量下手,分库分表。
面试官笑了,说:“这才是落地的答案,不是背八股文。”
慢查询优化的心法
说到底,慢查询优化不是一蹴而就的,它更像是一种“修炼”。
- 你要有耐心,去找出每一条慢 SQL 背后的原因;
- 你要有技巧,懂得什么时候用索引,什么时候用分表;
- 你还要有全局观,知道慢查询不只是开发的事,而是运维、DBA、业务一起的战斗。
我喜欢把优化慢查询,比作“修剑术”:
- SQL 是剑招;
- 索引是剑锋;
- 分表是你最后的大招。
修炼久了,你会发现自己在写 SQL 时自然会留意性能,而不是等到线上爆炸才来救火。
写在最后
如果把开发比作开车,SQL 就是你的“油门”,慢查询就是“刹车失灵”的时刻。
面试官问的这道题,其实是在考察:你有没有真正关注过性能?有没有在项目里动手优化过?
所以我的建议是:
- 平时写 SQL 多 explain;
- 多留意慢查询日志;
- 多和 DBA、运维沟通;
- 遇到性能问题别慌,按照“三板斧”走。
这样你就能给面试官一个既真实又专业的回答。
END
朋友们,你们有没有在项目里被慢查询坑过?你们都是怎么优化的?欢迎在评论区分享,让我们一起成长。
我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货!