文章目录
一、索引优化的三重境界
1.1 索引失效的六大经典场景(必考!)
最近帮学弟复盘面试,发现90%的同学栽在这个问题上!划重点:
- 最左前缀原则失效(where条件顺序不对)
- 索引列计算(比如
year(create_time)=2023
) - 类型转换(字符串字段用数字查询)
!=
或<>
操作符(全表扫描警告!)or
连接非索引列(索引合并可能触发但效率低)- 模糊查询
%
打头(like '张%'
可以走索引)
👉举个真实案例:某电商平台商品表sku_code
是varchar类型,开发小哥用where sku_code=20230415
查询,结果索引失效引发慢查询(类型转换导致)!
1.2 联合索引的排列组合玄学
面试官最爱连环问:“ABC三个字段的联合索引,where B=2 and A=1能命中吗?”
答案其实很反直觉:可以!因为MySQL优化器会自动调整条件顺序(但范围查询会阻断后续索引使用)。
1.3 覆盖索引的妙用
去年优化过一个千万级用户表,原查询select * from users where age>20
,改成select id,age
后性能提升8倍!原理很简单:直接从索引树拿数据,不需要回表。
二、执行计划深度解读(Explain高阶玩法)
2.1 关键指标四天王
- type列:从好到坏排序 system > const > ref > range > index > ALL
- rows列:估算扫描行数(与实际相差3倍以上就要警惕)
- Extra列:出现
Using filesort
或Using temporary
立即报警! - filtered列:过滤比例低于5%要考虑索引优化
2.2 索引下推(ICP)的魔法
MySQL5.6的黑科技!举个🌰:
-- 联合索引(age,city)
select * from users
where age>18
and city like '%上海%'
没有ICP时需要先回表再过滤城市,有ICP后直接在存储引擎层过滤,减少70%回表操作!
三、慢查询优化的三大杀器
3.1 改写SQL的奇技淫巧
最近刚解决的线上事故:某分页查询limit 100000,10
卡死,改成如下写法性能提升20倍:
-- 原写法(超慢)
select * from orders
order by create_time
limit 100000,10
-- 优化写法(先定位id)
select * from orders
where id >= (select id from orders order by create_time limit 100000,1)
order by create_time
limit 10
3.2 强制索引的利与弊
force index
不是银弹!上周生产环境有个坑:强制使用索引后反而更慢,因为数据分布变化导致索引不优。切记要结合analyze table
更新统计信息。
3.3 参数调优的禁忌领域
面试常问innodb_buffer_pool_size
设置多少合适?我的经验公式:
物理内存的50%-70%
,但超过64G的服务器建议设置40G左右(具体要看数据量)。曾见过设置80%导致OOM的惨案(血泪教训)!
四、高频灵魂拷问TOP5
Q1:count(*)和count(1)哪个更快?
真相可能让你吃惊:在MySQL5.7之后,两者性能完全一致!但count(列名)会跳过NULL值,要注意业务逻辑。
Q2:为什么不要用外键?
这是道送命题!参考答案:
- 影响写性能(每次都要检查约束)
- 分库分表时不友好
- 业务逻辑耦合度高
- 死锁概率增加(但要说清楚业务场景)
Q3:如何优雅地分库分表?
我的三板斧:
- 客户端分片(Sharding-JDBC)
- 代理层分片(MyCat)
- 业务双写+最终一致
重要提醒:单表500万就要开始规划,别等到炸了再处理!
Q4:死锁排查六脉神剑
上周刚解决的死锁案例:
show engine innodb status
查最新死锁日志- 分析lock_mode(X锁还是S锁)
- 查看等待资源
- 检查事务隔离级别
- 确认索引使用情况
- 用
select * from information_schema.innodb_trx
查活跃事务
Q5:主从延迟怎么破?
某电商大促时的解决方案:
- 半同步复制+并行复制
- 写后读主库机制
- 关键业务走主库查询
- 监控延迟时间(Seconds_Behind_Master)
五、实战案例分析(价值10w的教训)
去年双十一压测时,发现订单查询接口TP99飙升到2s。经过分析:
- 执行计划显示全表扫描
- 原来where条件中的
status
字段没有索引 - 加上索引后反而更慢?!(因为该字段区分度太低)
- 最终方案:建立
(status,create_time)
联合索引 - 配合业务改造,将状态查询改为时间范围查询
这个案例教会我:不要盲目加索引,要结合业务逻辑和数据分布!
💡调优必备工具清单
- 慢查询日志分析(mysqldumpslow)
- 实时监控(pt-query-digest)
- 压力测试(sysbench)
- 可视化工具(Archery)
- 锁分析(performance_schema)
最后的小贴士
面试时被问到不会的问题,可以说:“这个问题我之前主要聚焦在XX方面,对您说的这个点了解不深。不过根据我的经验,可能的解决思路是…”(亲测有效!)
调优就像破案,要有福尔摩斯的观察力+柯南的直觉+金田一的耐心。记住:每个慢查询背后,都藏着一个等待被发现的故事!