文章目录
一、面试官最爱问的SQL调优连环杀
最近帮学员复盘面试时,发现80%的SQL调优问题都逃不过这三个灵魂拷问(划重点!):
- “遇到慢查询怎么定位问题?”(必考!)
- “索引失效的常见场景有哪些?”(高频陷阱题)
- “怎么用执行计划分析性能瓶颈?”(区分水货的关键)
先别急着背答案!咱们先来看个真实案例:
某电商平台订单表(order)突然出现查询延迟,原始SQL长这样:
SELECT * FROM orders
WHERE create_time BETWEEN '2023-01-01' AND '2023-12-31'
ORDER BY total_price DESC
LIMIT 100;
(执行时间:8.7秒!)
二、实战调优四步走
Step 1:执行计划全解析
加上EXPLAIN后:
EXPLAIN SELECT * FROM orders...;
输出结果:
+----+-------------+-------+------+---------------+------+---------+------+--------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+--------+-----------------------------+
| 1 | SIMPLE | orders| ALL | NULL | NULL | NULL | NULL | 980000 | Using where; Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+--------+-----------------------------+
破案关键点:
type=ALL(全表扫描警告!)rows=98万(扫描数据量爆炸)Using filesort(文件排序要命)
Step 2:索引设计的艺术
常见翻车现场:
ALTER TABLE orders ADD INDEX idx_create_time (create_time);
(你以为这就完事了?Too young!)
正确姿势:
ALTER TABLE orders ADD INDEX idx_covering (create_time, total_price);
覆盖索引才是王道!既能过滤又能排序,直接省去回表操作。
Step 3:执行计划再验证
优化后的执行计划:
+----+-------------+-------+-------+---------------+-------------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+-------------+---------+------+------+-------------+
| 1 | SIMPLE | orders| range | idx_covering | idx_covering| 4 | NULL | 365 | Using where |
+----+-------------+-------+-------+---------------+-------------+---------+------+------+-------------+
性能提升点:
type=range(索引范围扫描)rows=365(扫描行数骤降)- 消失的
filesort(索引自带排序)
Step 4:终极优化
最后补刀:
SELECT create_time, total_price, order_no
FROM orders
WHERE create_time BETWEEN '2023-01-01' AND '2023-12-31'
ORDER BY total_price DESC
LIMIT 100;
(执行时间:0.02秒!)
核心技巧:
- 只取必要字段
- 利用覆盖索引
- 避免
SELECT *
三、索引失效的六大死亡场景
-
隐式类型转换(杀人于无形)
-- user_id是varchar类型时 SELECT * FROM users WHERE user_id = 10086; -
最左前缀原则(新手坟场)
INDEX (a,b,c) WHERE b=1 AND c=2 -- 索引失效! -
函数操作(索引杀手)
WHERE YEAR(create_time) = 2023 -
模糊查询(左%要命)
WHERE name LIKE '%张%' -
OR连接(索引终结者)
WHERE a=1 OR b=2 -
范围查询后的列(连环失效)
WHERE a>10 AND b=20 -- 只有a走索引
四、高级调优技巧(BAT高频考点)
1. 分页查询优化
原始分页:
SELECT * FROM table LIMIT 1000000, 10;
优化方案:
SELECT * FROM table
WHERE id > 1000000
ORDER BY id
LIMIT 10;
2. Join连接优化
三大原则:
- 小表驱动大表
- 被驱动表加索引
- 避免
SELECT *
3. 冷热数据分离
把历史数据归档到历史表:
-- 创建归档表
CREATE TABLE orders_archive LIKE orders;
-- 迁移数据
INSERT INTO orders_archive
SELECT * FROM orders
WHERE create_time < '2022-01-01';
-- 删除原表数据
DELETE FROM orders
WHERE create_time < '2022-01-01';
五、面试反杀技巧
当面试官问:“如果所有优化手段都用过了,查询还是慢怎么办?”
标准答案:
- 考虑分库分表(垂直/水平拆分)
- 引入读写分离架构
- 使用缓存中间件(Redis/Memcached)
- 升级硬件配置(最后手段)
加分回答:
“在我们之前项目中,当订单表突破500万时,我们采用TiDB分布式数据库,通过Region自动分裂实现水平扩展,QPS从200提升到2000+”
六、避坑指南
最近面试遇到的奇葩问题:
- “为什么索引不要超过5个字段?”
- “B+树的高度对查询有什么影响?”
- “怎么通过索引实现覆盖查询?”
建议把《MySQL技术内幕:InnoDB存储引擎》翻烂!特别是第六章索引算法和第七章锁机制,简直是面试答案书!
最后送大家一个调优口诀:
一查执行计划,二看索引情况,
三避全表扫描,四用覆盖索引,
五分页要优化,六拆冷热数据,
七上缓存大招,八用架构解忧
4676

被折叠的 条评论
为什么被折叠?



