Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > mysql慢查询

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

作者:五阿哥永琪

本文介绍了如何定位和解决MySQL慢查询,首先,需要开启和检查慢查询日志,然后通过分析日志和使用`EXPLAIN`语句来定位问题,接着,文章讨论了基础优化、JOIN优化、子查询优化以及如何创建和使用索引,通过这些方法,可以有效提高MySQL的性能,感兴趣的朋友跟随小编一起看看吧

如何定位并解决慢查询?

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条件

-- ❌ 索引失效 
SELECT * 
FROM orders 
WHERE YEAR(create_time) = 2024; 
-- ✅ 使用范围查询,可走索引 
SELECT * 
FROM orders 
WHERE create_time >= '2024-01-01' AND create_time < '2025-01-01';

3. 合理使用索引

4. 避免全表扫描

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

EXPLAIN SELECT * FROM products WHERE category_id = 10;

二、JOIN优化(多表查询)

1. 大表驱动小表

2. 确保JOIN字段都有索引

3. 避免多层嵌套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;

分页优化

​
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慢查询内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文