当前位置: 代码网 > it编程>数据库>Mysql > MySQL 慢查询定位与 SQL 性能优化实战教程

MySQL 慢查询定位与 SQL 性能优化实战教程

2025年12月17日 Mysql 我要评论
如何定位并解决慢查询?1. 开启/检查慢日志看一下是否开启慢日志show variables like 'slow_query_log';show variables like 'long_query

如何定位并解决慢查询?

1. 开启/检查慢日志

  • 看一下是否开启慢日志
show variables like 'slow_query_log';
show variables like 'long_query_time';
show variables like 'slow_query_log_file';
  • 如果未开启,临时开启(生产环境建议永久配置):
set global slow_query_log = on; 
set global long_query_time = 1;

2. 分析日志

mysqldumpslow(mysql 自带)

# 按执行次数排序前10条
  mysqldumpslow -s c -t 10 /var/log/mysql/slow.log
  # 按总耗时排序前10条
  mysqldumpslow -s t -t 10 /var/log/mysql/slow.log

3. 用explain分析执行计划

在sql前面加explain

explain select id, order_no 
from orders 
where user_id = 100 and create_time >= '2024-01-01' 
order by create_time desc;
  • 重点查看四个字段
字段看什么
type是否出现 all(全表扫描)
rows扫描行数是否过大
key是否使用到了正确索引
extra是否出现 using filesortusing temporary

sql优化?

一、基础优化

1. 避免select *

-- ❌ 不推荐 
select * from users; 
-- ✅ 推荐 
select id, name, email from users;

2. 使用合适的where条件

  • 尽量在where中使用索引字段
  • 避免对字段进行函数操作或类型转换(导致索引失效)
-- ❌ 索引失效 
select * 
from orders 
where year(create_time) = 2024; 
-- ✅ 使用范围查询,可走索引 
select * 
from orders 
where create_time >= '2024-01-01' and create_time < '2025-01-01';

3. 合理使用索引

  • 对经常用于where、join、order by、group by的列建立索引
  • 比卖你过度索引(影响写入性能)
  • 考虑使用复合索引(最左前缀原则)

4. 避免全表扫描

通过explain检查是否使用了索引

explain select * from products where category_id = 10;

二、join优化(多表查询)

1. 大表驱动小表

  • 在mysql中,通常将小结果姐放在left,大表在right

2. 确保join字段都有索引

  • 两个表关联字段都应该有索引

3. 避免多层嵌套join

  • 复杂join可拆分为多个简单查询

三、子查询 vsjoin

子查询在某些数据库中效率较低,可以尝试改成join

-- ❌ 子查询(可能低效) 
select * 
from users 
where id in (select user_id from orders where amount > 100); 
-- ✅ 改写为 
join select distinct u.* 
from users u 
join orders o on u.id = o.user_id 
where o.amount > 100;

分页优化

  • 深分页(如limit 100000,20)性能查,因为要跳过大量的数据
    • 优化方案:
      • 使用游标分页(基于上一页最后一条记录的id或时间):
​
select * from messages 
where id > 100000 
order by id 
limit 20;
​

如何创建、使用索引?

索引介绍

索引类型说明
主键索引聚簇索引,数据按主键物理存储,每一张表只能一个
唯一索引不允许出现重复值
普通索引最基本的索引,允许重复和null
全文索引用于文本搜索
前缀索引对字符串类的前n个字段创建索引,节省空间
覆盖索引非独立类型,查询字段全部包含在索引中,无需回表

一、创建索引

1. 创建普通索引

-- 方法1:create index(推荐用于已有表) 
create index index_name on table_name (column_name); 
-- 示例:在 users 表的 email 字段上创建索引 
create index idx_email on users (email);

2. 创建唯一索引

create unique index idx_username on users (username);

3. 创建复合索引

  • 符合索引使用时必须遵循最左前缀原则,查询时必须包含最左边的列才能生效
-- 按顺序:先按 category_id,再按 created_at 排序 
create index idx_category_created on products (category_id, created_at);

4. 在建表时直接定义索引

create table orders (
	id bigint primary key auto_increment, 
	user_id int not null, 
	status varchar(20), 
	created_at datetime, 
	-- 主键自动创建聚簇索引(innodb) 
	index idx_user_status (user_id, status), -- 普通复合索引 
	unique index uk_order_no (order_no) -- 唯一索引 
	);

5. 添加主键(自动添加聚簇索引)

alter table table_name add primary key (id);

到此这篇关于mysql 慢查询定位与 sql 性能优化实战指南的文章就介绍到这了,更多相关mysql慢查询内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com