手撕SQL调优面试:这些高频考点你必须知道!(附真实案例解析)

一、面试官最爱问的SQL调优连环杀

最近帮学员复盘面试时,发现80%的SQL调优问题都逃不过这三个灵魂拷问(划重点!):

  1. “遇到慢查询怎么定位问题?”(必考!)
  2. “索引失效的常见场景有哪些?”(高频陷阱题)
  3. “怎么用执行计划分析性能瓶颈?”(区分水货的关键)

先别急着背答案!咱们先来看个真实案例:

某电商平台订单表(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 *

三、索引失效的六大死亡场景

  1. 隐式类型转换(杀人于无形)

    -- user_id是varchar类型时
    SELECT * FROM users WHERE user_id = 10086; 
    
  2. 最左前缀原则(新手坟场)

    INDEX (a,b,c)
    WHERE b=1 AND c=2 -- 索引失效!
    
  3. 函数操作(索引杀手)

    WHERE YEAR(create_time) = 2023
    
  4. 模糊查询(左%要命)

    WHERE name LIKE '%张%'
    
  5. OR连接(索引终结者)

    WHERE a=1 OR b=2
    
  6. 范围查询后的列(连环失效)

    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';

五、面试反杀技巧

当面试官问:“如果所有优化手段都用过了,查询还是慢怎么办?”

标准答案

  1. 考虑分库分表(垂直/水平拆分)
  2. 引入读写分离架构
  3. 使用缓存中间件(Redis/Memcached)
  4. 升级硬件配置(最后手段)

加分回答
“在我们之前项目中,当订单表突破500万时,我们采用TiDB分布式数据库,通过Region自动分裂实现水平扩展,QPS从200提升到2000+”

六、避坑指南

最近面试遇到的奇葩问题:

  • “为什么索引不要超过5个字段?”
  • “B+树的高度对查询有什么影响?”
  • “怎么通过索引实现覆盖查询?”

建议把《MySQL技术内幕:InnoDB存储引擎》翻烂!特别是第六章索引算法和第七章锁机制,简直是面试答案书!

最后送大家一个调优口诀:
一查执行计划,二看索引情况,
三避全表扫描,四用覆盖索引,
五分页要优化,六拆冷热数据,
七上缓存大招,八用架构解忧

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值