Article
引言
在学习数据库的过程中,我发现性能优化是一个非常重要的话题。本文总结了我学到的一些 MySQL 优化技巧。
索引优化
1. 合理使用索引
索引可以大大提高查询速度,但也会增加写入和更新的成本。
-- 创建单列索引
CREATE INDEX idx_username ON users(username);
-- 创建复合索引
CREATE INDEX idx_name_age ON users(name, age);
2. 避免索引失效
以下情况会导致索引失效:
- 使用
!=或<>操作符 - 使用
OR连接条件 - 在索引列上使用函数
- 使用
LIKE以通配符开头
-- ❌ 索引失效
SELECT * FROM users WHERE YEAR(created_at) = 2024;
-- ✅ 索引有效
SELECT * FROM users WHERE created_at >= '2024-01-01'
AND created_at < '2025-01-01';
查询优化
1. 避免 SELECT *
只查询需要的列:
-- ❌ 不推荐
SELECT * FROM users WHERE id = 1;
-- ✅ 推荐
SELECT id, username, email FROM users WHERE id = 1;
2. 使用 LIMIT 限制结果
SELECT id, username FROM users
WHERE status = 1
ORDER BY created_at DESC
LIMIT 10;
3. 优化 JOIN 查询
-- 使用 INNER JOIN 代替子查询
SELECT u.username, o.order_no
FROM users u
INNER JOIN orders o ON u.id = o.user_id
WHERE u.status = 1;
表设计优化
1. 选择合适的数据类型
- 使用
INT而不是BIGINT(如果范围够用) - 使用
TIMESTAMP而不是DATETIME(节省空间) - 使用
ENUM代替字符串(状态字段)
CREATE TABLE users (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
status ENUM('active', 'inactive', 'banned') DEFAULT 'active',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
2. 表的垂直拆分
将不常用的大字段拆分到另一个表:
-- 主表
CREATE TABLE users (
id INT PRIMARY KEY,
username VARCHAR(50),
email VARCHAR(100)
);
-- 扩展表
CREATE TABLE user_profiles (
user_id INT PRIMARY KEY,
bio TEXT,
avatar_url VARCHAR(255),
FOREIGN KEY (user_id) REFERENCES users(id)
);
配置优化
重要的配置参数
# my.cnf 配置文件
# 缓冲池大小(设置为物理内存的 50-80%)
innodb_buffer_pool_size = 4G
# 最大连接数
max_connections = 200
# 查询缓存(MySQL 8.0 已移除)
query_cache_size = 0
# 慢查询日志
slow_query_log = 1
long_query_time = 2
EXPLAIN 分析查询
使用 EXPLAIN 查看查询执行计划:
EXPLAIN SELECT * FROM users WHERE username = 'john';
重点关注的字段:
- type: 连接类型(const > eq_ref > ref > range > index > all)
- key: 使用的索引
- rows: 扫描的行数
- Extra: 额外信息
实战案例
案例:优化慢查询
问题查询:
SELECT * FROM orders
WHERE DATE_FORMAT(created_at, '%Y-%m') = '2024-11'
ORDER BY id DESC
LIMIT 10;
优化后:
SELECT id, order_no, user_id, total_amount, created_at
FROM orders
WHERE created_at >= '2024-11-01'
AND created_at < '2024-12-01'
ORDER BY id DESC
LIMIT 10;
改进点:
- 避免在索引列使用函数
- 只查询需要的字段
- 使用范围查询替代函数计算
监控工具
推荐使用的工具:
- MySQL Workbench: 可视化管理工具
- Percona Toolkit: 性能分析工具集
- mysqldumpslow: 慢查询日志分析
- pt-query-digest: 查询分析工具
学习总结
- 索引不是越多越好:需要权衡查询和写入性能
- 定期分析慢查询:找出性能瓶颈
- 合理的表设计:从一开始就要考虑优化
- 持续监控:使用工具监控数据库性能
参考资料
- 《高性能MySQL》
- MySQL 官方文档
- MySQL Performance Blog
数据库优化是一个持续的过程,需要不断学习和实践!