SQL 优化
本章节介绍 MySQL SQL 语句与索引的优化策略。
执行计划分析
sql
EXPLAIN SELECT * FROM orders WHERE user_id = 1 AND status = 'PAID';关键字段:
| 字段 | 说明 |
|---|---|
type | 访问类型,优先级:const > eq_ref > ref > range > index > ALL |
key | 实际使用的索引 |
rows | 预估扫描行数(越小越好) |
Extra | Using index(覆盖索引)、Using filesort(需优化) |
索引优化
sql
-- 联合索引遵循最左前缀原则
CREATE INDEX idx_user_status_time ON orders(user_id, status, create_time);
-- 覆盖索引避免回表
SELECT order_no, status FROM orders WHERE user_id = 1; -- 若索引包含这三列则无需回表索引失效场景:
WHERE YEAR(create_time) = 2024(对列使用函数)WHERE phone = 13800138000(字符串列用数字,隐式转换)WHERE name LIKE '%张'(左模糊)WHERE a = 1 OR b = 2(OR 条件中 b 无索引)
慢查询优化思路
- 开启慢查询日志:
slow_query_log = 1, long_query_time = 1 - 用
EXPLAIN分析执行计划 - 针对性添加索引或改写 SQL
- 大表考虑分页优化:
sql
-- 避免深分页(offset 大时性能差)
-- 差:
SELECT * FROM orders LIMIT 100000, 20;
-- 好:基于游标的分页
SELECT * FROM orders WHERE id > 100000 LIMIT 20;常见优化手段
| 场景 | 优化方案 |
|---|---|
| 大量数据统计 | 异步计算 + 缓存结果 |
| 批量插入 | INSERT INTO ... VALUES (),(),() 批量写入 |
| 联表查询慢 | 检查关联字段是否有索引 |
| 锁等待 | 缩短事务范围,避免在事务中做耗时操作 |
