前言
在实际开发中,数据库查询性能往往直接决定系统的响应速度。很多开发者在系统初期并不会遇到明显的性能问题,但随着数据量增长,慢查询、接口超时、数据库cpu飙升等问题会逐渐出现。此时,mysql 查询优化就成为每个后端工程师必须掌握的核心技能之一。
本文将按照技术博客常见的结构,从 概念 → 原理 → 实践 → 常见误区 → 面试考点,逐步深入讲解 mysql 查询优化。
一、什么是 mysql 查询优化
**mysql 查询优化(query optimization)**指的是通过调整 sql语句、索引结构、表结构以及数据库配置,让数据库在执行查询时使用更高效的执行方式,从而减少:
- 磁盘io
- cpu计算
- 数据扫描量
- 查询时间
简单理解:
用更少的资源,更快地得到结果。
例如:
低效sql:
select * from user where name = 'tom';
优化后:
select id,name from user where name = 'tom';
优化点:
- 避免
select * - 减少返回字段
- 提高查询效率
二、为什么 mysql 查询优化很重要
在真实业务中,数据库通常是系统性能瓶颈。
常见场景:
| 场景 | 问题 |
|---|---|
| 电商订单系统 | 查询订单慢 |
| 社交系统 | 用户列表加载慢 |
| 日志系统 | 大表查询卡顿 |
| 统计分析 | sql执行时间过长 |
如果sql没有优化:
可能导致:
- 数据库cpu 100%
- 慢查询大量积累
- 系统接口超时
- 服务器成本增加
因此:
sql优化是后端工程师必须具备的核心能力之一。
三、mysql 查询执行流程(理解优化的基础)
一条sql执行的大致流程:
客户端请求
↓
连接器
↓
查询缓存(mysql8已移除)
↓
解析器(sql语法解析)
↓
优化器(选择最优执行计划)
↓
执行器
↓
存储引擎读取数据
关键点:
优化器会决定:
- 是否使用索引
- 使用哪个索引
- 表连接顺序
- 是否使用临时表
- 是否排序
优化sql的核心就是:
让优化器选择更优的执行计划
四、sql 查询优化核心原则
sql优化通常遵循以下几个原则:
1 避免 select *
不推荐:
select * from user;
原因:
- 读取不必要字段
- 增加io
- 影响覆盖索引
推荐:
select id,name,email from user;
2 尽量使用索引
没有索引:
全表扫描
有索引:
快速定位数据
示例:
create index idx_name on user(name);
查询:
select * from user where name='tom';
3 避免在索引列上使用函数
错误示例:
select * from user where year(create_time)=2024;
原因:
函数会导致 索引失效
正确方式:
select * from user where create_time >= '2024-01-01' and create_time < '2025-01-01';
4 避免隐式类型转换
错误示例:
select * from user where phone = 123456;
如果 phone 是字符串:
索引可能失效
正确:
select * from user where phone = '123456';
5 使用 limit 限制返回数据
错误:
select * from log;
正确:
select * from log limit 100;
五、常见 sql 优化技巧
1 使用 explain 分析执行计划
最重要的优化工具:
explain select * from user where id=1;
关键字段:
| 字段 | 含义 |
|---|---|
| type | 访问类型 |
| key | 使用的索引 |
| rows | 扫描行数 |
| extra | 额外信息 |
访问类型性能排序:
system > const > eq_ref > ref > range > index > all
最差:
all(全表扫描)
2 合理设计索引
索引类型:
- 主键索引
- 唯一索引
- 普通索引
- 联合索引
联合索引示例:
create index idx_user_age_city on user(age,city);
查询:
select * from user where age=20 and city='beijing';
遵循原则:
最左前缀原则
3 覆盖索引
当查询字段全部在索引中:
数据库不需要回表。
示例:
索引:
(name,age)
查询:
select name,age from user where name='tom';
优势:
- 减少io
- 提高速度
4 避免大偏移量分页
错误:
select * from order limit 100000,10; //获取第100001-100010条记录(共10条)
原因:
数据库需要扫描:
100010 行
优化方案:
使用 id分页
select * from order where id > 100000 limit 10;
5 使用合理的 join
避免:
多表复杂嵌套
推荐:
- 小表驱动大表
- 使用索引
示例:
select u.name,o.amount from user u join order o on u.id=o.user_id;
六、常见 sql 优化误区(易错点)
误区1:索引越多越好
错误原因:
- 增加写入成本
- 占用空间
- 降低更新性能
原则:
只为查询创建必要索引
误区2:like 一定走索引
错误:
like '%abc'
不会使用索引。
正确:
like 'abc%'
误区3:order by 一定慢
如果排序字段有索引:
排序其实很快。
例如:
order by create_time
七、mysql 查询优化使用场景
常见优化场景:
1 大数据量表查询
例如:
千万级订单表
需要:
- 索引优化
- 分页优化
2 统计查询
例如:
select count(*) from order;
优化方式:
- 使用缓存
- 使用汇总表
3 高并发接口
例如:
商品详情接口
优化:
- 索引
- 缓存
- 减少sql复杂度
八、mysql 查询优化实战步骤
实际工作中通常这样优化:
第一步:找到慢sql
开启慢查询日志:
slow_query_log = on
第二步:分析执行计划
使用:
explain
第三步:添加或调整索引
常见:
- 单列索引
- 联合索引
第四步:重写sql
例如:
- 避免子查询
- 使用join
- 减少扫描行数
九、mysql 面试常考点总结
数据库面试中经常考:
1 为什么索引能提高查询效率?
核心原因:
- b+树结构
- 减少磁盘io
2 什么是最左前缀原则?
联合索引:
(a,b,c)
可用:
a a,b a,b,c
不可用:
b c b,c
3 什么情况下索引会失效?
常见情况:
- 使用函数
- 隐式类型转换
- like
%abc - or连接不同字段
- 范围查询后继续使用索引列
4 explain 中 type=all 代表什么?
全表扫描
性能最差。
5 什么是回表查询?
使用二级索引找到主键,再去主键索引查数据。
十、总结
mysql 查询优化的核心可以总结为 六个字:
减少扫描数据
常见优化手段包括:
- 合理使用索引
- 避免 select *
- 使用 explain 分析执行计划
- 减少大分页
- 避免索引失效
- 使用覆盖索引
到此这篇关于mysql数据库查询优化技巧的文章就介绍到这了,更多相关mysql查询优化技巧内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论