嘿,大家好呀,我是你们的老朋友小米,那个在数据库世界里摸爬滚打了快十年的程序员。

这不,最近在面试一个 MySQL DBA 的岗位,刚落座,面试官就丢过来一个“送命题”:

“你觉得使用索引查询,一定能提高查询的性能吗?”

这问题看起来是不是特别基础?可你要真答“是”,恐怕你就只能“谢谢参与”了。

今天这篇文章,就来和你唠唠这个“经典陷阱题”背后的门道,顺便也讲讲我和这个问题的“爱恨情仇”。

面试现场,我差点就踩坑了!

先来回放下我那次的真实面试。

面试官大概40岁出头,技术底子很硬,一看就是那种“老数据库人”。他刚问完问题,就抿了一口茶,似笑非笑地看着我,仿佛在说:你要是敢说“能”,咱这面就结束了。

我当时脑子一热,差点就说出“当然能提升性能啊,索引就是干这个的!”但转念一想,不对劲……

于是我稳了稳情绪,笑着说:

“使用索引大概率能提升查询性能,但不一定。如果用得不合适,反而可能拖慢查询速度,甚至让数据库崩溃。”

面试官微微一笑,点了点头:“那你展开讲讲。”

这下,轮到我发力了。

索引不是银弹,它也有脾气

我们都知道,索引就像书的目录,它能帮你快速定位到某一页内容,而不是从头翻到尾。这个类比很经典。

但你想想,如果你那本书的目录是乱的,或者查的是个没进目录的小章节,是不是反而更费事?

MySQL 中,索引主要是为了加速数据检索,特别是WHERE、JOIN、ORDER BY、GROUP BY这些场景。但使用不当,确实有可能导致以下几种问题:

第一类:用不到索引,但你以为用了

还记得我刚入职第一家公司,年轻气盛,撸了条看似很“规范”的 SQL:

MySQL社招经典送命题:使用索引一定能提升性能吗?_字段

我自信满满,心想“我可是加了索引的啊,create_time 上有索引,稳了”。

结果执行计划一看——全表扫描

我一脸懵,赶紧找老大求教。他瞥了眼 SQL,说了句:

“你这个写法,等于告诉 MySQL:先对每一行数据执行 YEAR() 函数,再筛选,不走索引,正常。”

那天我才明白:对索引列做了函数操作,就废了索引

改成这样才对:

MySQL社招经典送命题:使用索引一定能提升性能吗?_SQL_02

这才是真正能让索引“跑起来”的写法。

第二类:索引选错了,走得慢还白费力

有一回项目上线后频繁报警,业务反馈“查订单慢得像乌龟”。我一查,SQL 是这样的:

MySQL社招经典送命题:使用索引一定能提升性能吗?_SQL_03

orders 表是个大表,status 和 user_id 都是索引字段,但创建的时候顺序是 KEY idx_status_user (status, user_id)。

问题是,大量业务查询只用 user_id。于是,这种 SQL 并不能命中最左前缀索引,只能降级为扫描。

我试着加个联合索引 (user_id, status),结果查询性能蹭蹭上涨,报警也消停了。

这教训告诉我:

索引顺序错了,就像钥匙反着插——看似对,实则不通。

第三类:索引虽走了,但比全表扫描还慢

是的,听起来很离谱,但这事我真的经历过。

那次是查一个低选择性的字段,比如 gender = 'male',而表里 90% 都是男的。

索引确实走了,但 MySQL 要频繁从索引回表去取数据(回表是从索引跳转到原表行取数据的操作),结果一条语句执行了几十秒。

后来我强制走全表扫描,反而性能提高了三倍。

所以记住:

低选择性的字段,不要轻易单独加索引。

比如性别、布尔值、0/1 状态这种,往往适合联合索引,比如 (gender, age),让索引更“具体”。

第四类:索引太多,反而拖累写性能

之前帮朋友优化他们公司的用户表,发现光索引就有 14 个!只要插入一条新用户数据,整个库都开始“卡顿”。

为啥?因为每次写操作,MySQL 都得维护所有相关的索引,这可不轻松。

我和他讨论后,果断砍掉了一半不常用的索引,写入性能提升 60%。

索引多,不等于强,要根据业务查询场景精挑细选。

第五类:复合索引用错了,等于没用

这点尤其容易踩坑。

假设我们有个索引 (user_id, order_id, create_time),它能支持哪些查询?

答案是:

  • WHERE user_id = ? ✅
  • WHERE user_id = ? AND order_id = ? ✅
  • WHERE user_id = ? AND order_id = ? AND create_time = ? ✅
  • WHERE order_id = ? ❌
  • WHERE create_time = ? ❌

为什么?因为复合索引是基于最左前缀原则建立的。你不从最左边开始用,它就不理你。

很多新手以为“包含了字段,就能用”,其实这跟“看到人影就以为是你妈来接你放学”一样盲目。

那到底什么时候该用索引?

我用几个字总结:常用、区分、前缀、顺序、回表少。

  • 常用字段:频繁出现在 WHERE、JOIN、GROUP BY 的字段。
  • 高区分度:比如手机号、用户ID。
  • 最左前缀:复合索引从左到右顺序不能错。
  • 顺序匹配:ORDER BY 顺序尽量与索引一致。
  • 减少回表:覆盖索引能极大提升效率。

你只有真正理解这些,才能在面试时不被问住,在实战中稳稳拿下优化任务。

总结

言归正传,这道题的参考答案应该是这样答的:

使用索引通常能提升查询性能,但前提是索引设计合理、SQL 写法正确。如果使用了函数、类型不一致、索引选择性太低、顺序不对、没有覆盖索引等情况,都可能导致走不了索引,甚至让性能变差。理解索引底层结构和执行计划,是写出高性能 SQL 的前提。

如果你能补充个两三段实际场景,那就不仅答得完整,还答得高级。

最后,小米的一个小建议

下次面试遇到类似问题,千万别急着回答“是”或“不是”,而是先分析前提,再讲场景,最后总结原则

数据库优化是一门经验学科,别指望靠死记硬背秒杀面试官。真正让你从“技术候选人”变成“业务推动者”的,是你讲得出问题,拆得掉坑,带得动项目。

如果你在 MySQL 优化路上也踩过坑,欢迎留言告诉我,一起“以坑为师”,共同进步!

END

我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货!