sudo-iのBlog

  • 🍟首页
  • 🍊目录
    • 技术分享
    • vps教程
    • 软件分享
    • 干货分享
  • 🍎链接
  • 🍓工具
    • 🌽IP路由追踪
    • 域名被墙检测
    • KMS激活
    • 域名whois查询
  • 🍕联系
  • 🍌登录
Sudo-i
关注互联网,生活,音乐,乐此不疲
  1. 首页
  2. 干货分享
  3. 正文

MySQL 数据库性能优化:从 10 秒到 100 毫秒的实战指南

5 3 月, 2026 55点热度 0人点赞 0条评论

MySQL 数据库性能优化:从 10 秒到 100 毫秒的实战指南

在生产环境中,数据库性能问题往往是系统瓶颈的根源。本文将分享实际的 MySQL 优化经验,帮助你将查询时间从秒级降低到毫秒级。

一、诊断性能问题

在优化之前,首先需要找到性能瓶颈所在。

1.1 启用慢查询日志

-- 查看慢查询日志状态
SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'long_query_time';

-- 开启慢查询日志
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;  -- 记录超过 1 秒的查询
SET GLOBAL log_queries_not_using_indexes = 'ON';

1.2 分析慢查询

# 使用 mysqldumpslow 分析慢查询日志
mysqldumpslow -s t -t 10 /var/log/mysql/mysql-slow.log

# 或使用 pt-query-digest(Percona Toolkit)
pt-query-digest /var/log/mysql/mysql-slow.log

二、索引优化策略

2.1 创建合适的索引

-- 查看表索引
SHOW INDEX FROM users;

-- 为常用查询字段创建索引
CREATE INDEX idx_email ON users(email);
CREATE INDEX idx_created_at ON orders(created_at);

-- 创建复合索引(注意字段顺序)
CREATE INDEX idx_user_status_created ON orders(user_id, status, created_at);

2.2 索引最佳实践

  • 最左前缀原则:复合索引 (a,b,c) 可以支持 a、(a,b)、(a,b,c) 的查询
  • 选择性高的字段优先:性别字段不适合单独建索引
  • 避免过度索引:每个索引都会增加写入开销
  • 覆盖索引:查询字段都在索引中可避免回表

2.3 使用 EXPLAIN 分析查询

EXPLAIN SELECT * FROM orders 
WHERE user_id = 123 
AND status = 'pending' 
ORDER BY created_at DESC 
LIMIT 10;

-- 关注以下字段:
-- type: 访问类型(system > const > eq_ref > ref > range > index > ALL)
-- key: 实际使用的索引
-- rows: 预估扫描行数
-- Extra: 额外信息(Using index 表示覆盖索引,Using filesort 需要优化)

三、查询优化技巧

3.1 避免 SELECT *

-- ❌ 不推荐
SELECT * FROM users WHERE id = 1;

-- ✅ 推荐:只查询需要的字段
SELECT id, name, email FROM users WHERE id = 1;

3.2 优化分页查询

-- ❌ 深度分页性能差
SELECT * FROM orders ORDER BY created_at DESC LIMIT 100000, 20;

-- ✅ 使用游标分页
SELECT * FROM orders 
WHERE created_at < '2026-01-01 00:00:00' 
ORDER BY created_at DESC 
LIMIT 20;

-- ✅ 或使用子查询优化
SELECT o.* FROM orders o
INNER JOIN (
    SELECT id FROM orders ORDER BY created_at DESC LIMIT 100000, 20
) tmp ON o.id = tmp.id;

3.3 优化 JOIN 操作

-- ✅ 确保 JOIN 字段有索引
-- ✅ 小表驱动大表
-- ✅ 避免多表 JOIN(超过 3 表考虑应用层组装)

-- 优化前
SELECT * FROM orders o
LEFT JOIN users u ON o.user_id = u.id
LEFT JOIN products p ON o.product_id = p.id
WHERE o.created_at > '2026-01-01';

-- 优化后:拆分查询,应用层组装
SELECT id, user_id, product_id FROM orders WHERE created_at > '2026-01-01';
SELECT id, name FROM users WHERE id IN (...);
SELECT id, name FROM products WHERE id IN (...);

四、表结构优化

4.1 选择合适的数据类型

-- ❌ 浪费空间
CREATE TABLE users (
    id INT,              -- 如果 ID 不会超过 65535,用 SMALLINT
    phone VARCHAR(255),  -- 手机号用 VARCHAR(11) 或 CHAR(11)
    status TINYINT       -- 状态用 TINYINT 而非 INT
);

-- ✅ 优化后
CREATE TABLE users (
    id SMALLINT UNSIGNED,
    phone CHAR(11),
    status TINYINT
);

4.2 垂直分表

-- 将大字段分离到扩展表
CREATE TABLE users (
    id INT PRIMARY KEY,
    name VARCHAR(50),
    email VARCHAR(100),
    created_at TIMESTAMP
);

CREATE TABLE users_profile (
    user_id INT PRIMARY KEY,
    bio TEXT,
    avatar VARCHAR(255),
    settings JSON
);

五、配置优化

5.1 关键配置参数

# my.cnf 优化配置

[mysqld]
# 内存分配
innodb_buffer_pool_size = 4G        # 物理内存的 50-70%
innodb_log_file_size = 512M
innodb_log_buffer_size = 64M

# 连接数
max_connections = 500
thread_cache_size = 100

# 查询缓存(MySQL 5.7 及之前)
query_cache_size = 64M
query_cache_type = 1

# InnoDB 设置
innodb_flush_log_at_trx_commit = 2  # 1=最安全,2=性能更好
innodb_flush_method = O_DIRECT
innodb_io_capacity = 2000

# 日志
slow_query_log = 1
long_query_time = 1
log_queries_not_using_indexes = 1

六、实战案例

案例:订单查询从 10 秒优化到 100 毫秒

原始查询:

SELECT * FROM orders 
WHERE user_id = 12345 
AND created_at > '2026-01-01' 
ORDER BY created_at DESC;
-- 执行时间:10.5 秒,扫描 500 万行

优化步骤:

  1. 创建复合索引:CREATE INDEX idx_user_created ON orders(user_id, created_at);
  2. 只查询必要字段
  3. 添加 LIMIT 限制

优化后:

SELECT id, order_no, amount, status, created_at 
FROM orders 
WHERE user_id = 12345 
AND created_at > '2026-01-01' 
ORDER BY created_at DESC 
LIMIT 20;
-- 执行时间:85 毫秒,扫描 20 行

七、监控与维护

7.1 实时监控

-- 查看当前连接
SHOW PROCESSLIST;

-- 查看表锁
SHOW OPEN TABLES WHERE In_use > 0;

-- 查看 InnoDB 状态
SHOW ENGINE INNODB STATUS;

-- 查看性能指标
SHOW STATUS LIKE 'Threads_connected';
SHOW STATUS LIKE 'Innodb_buffer_pool_reads';

7.2 定期维护

-- 分析表(更新统计信息)
ANALYZE TABLE orders;

-- 优化表(整理碎片)
OPTIMIZE TABLE orders;

-- 检查表完整性
CHECK TABLE orders;

总结

MySQL 性能优化是一个系统工程,需要:

  1. ✅ 建立监控体系,及时发现慢查询
  2. ✅ 合理使用索引,避免全表扫描
  3. ✅ 优化 SQL 语句,减少不必要的数据读取
  4. ✅ 根据业务特点调整表结构
  5. ✅ 配置合适的服务器参数
  6. ✅ 定期维护,保持数据库健康

记住:优化不是一次性的工作,而是需要持续关注和调整的过程。建立完善的监控和告警机制,让性能问题在影响用户之前就被发现和解决。

无关联文章

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: 暂无
最后更新:5 3 月, 2026

李炫炫

这个人很懒,什么都没留下

点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

COPYRIGHT © 2025 sudo-iのBlog. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

鲁ICP备2024054662号

鲁公网安备37108102000450号