一、SQL优化整体思路(面试万能框架:架构→索引→语句→执行计划→兜底)
先看执行计划explain → 加合理索引 → 改写SQL语法 → 优化业务逻辑 → 架构分层兜底(缓存/分库分表)
1 索引优化(高频核心,必背)
- 优先满足最左前缀原则,联合索引字段顺序:等值+范围
- 避免索引失效:
- 禁止
like '%xx'前缀模糊 - 不要对索引列运算/函数:
date(create_time)、order by id+1 - 隐式类型转换(字符串和数字对比)
or导致失效,改用union all
- 区分聚集索引/二级索引,避免回表:覆盖索引
- 控制索引数量,写入高频表索引不宜过多
2 SQL语句写法优化
- 杜绝
select *,按需查字段,减少网络+内存开销 - 分页深翻优化:
limit 100000,10→ 主键定位where id>100000 limit 10 in数据量大改用join;小表驱动大表- 尽量减少子查询、嵌套查询;能用join别用exists/in乱嵌套
- 批量操作:batch批量insert/update,减少频繁交互
- 事务控制范围小,避免长事务锁表、MVCC堆积
3 Explain执行计划分析(面试标准话术)
重点看:
- type:优先 range/ref > 最差 all全表扫描
- key:是否真正命中索引
- rows:扫描行数越少越好
- Extra:出现 Using filesort / Using temporary 必须优化排序分组
4 业务&设计层面优化
- 大字段(text/blob)拆分垂直分表
- 时间、状态、基础筛选字段建立常规索引
- 合理冗余字段,减少多表join联查
- 冷热数据分离,归档历史数据减小表体量
5 架构兜底优化(高阶加分,贴合你10年经验)
- 热点数据Redis缓存,击穿/穿透/雪崩防护
- 千万级大表:水平分库分表(Sharding-JDBC)
- 复杂统计、报表走ES/ClickHouse离线分析,不压主库
- 读写分离:主库写、从库读
二、1分钟连贯口述回答(直接背,Java后端通用)
平时做SQL优化,我首先会通过 Explain 执行计划 定位慢SQL瓶颈,看扫描行数、type类型、有没有全表扫描、是否出现文件排序临时表。
索引层面遵循最左前缀原则,设计联合索引,打造覆盖索引减少回表;同时规避索引失效场景,比如前缀模糊查询、索引列函数运算、隐式类型转换这些坑。
SQL写法上拒绝 select *,按需取字段;深分页用主键偏移优化;大in改join、控制join表数量,缩小事务粒度避免长事务。
表结构设计上做冷热拆分、大字段垂直分表,必要时做数据归档减负。
架构层面热点数据上Redis缓存扛压,海量数据做读写分离、分库分表,复杂多维统计走ES、ClickHouse卸压MySQL,整体从语句、索引、架构多层落地优化,解决慢查询、数据库CPU高、连接打满等线上问题。
三、高频追问标准答案
1 为什么like %xxx不走索引?
前缀模糊无法走B+树有序检索,只能全表扫描;业务必要可用ES全文检索替代。
2 Using filesort怎么解决?
排序字段没索引 → 给order by字段建立联合索引,让排序走索引有序性,避免磁盘文件排序。
3 limit 100000,10慢如何优化?
跳过数据需要大量扫描排序;先用主键where id>阈值快速定位起点,再limit取少量数据,大幅减少扫描行数。