优化前必须备份数据,防止误操作导致数据丢失。使用mysqldump工具备份指定数据库:
mysqldump -u root -p your_database > /path/to/backup.sql
其中your_database为需备份的数据库名,/path/to/backup.sql为备份文件路径。
通过以下工具定位当前数据库的性能瓶颈:
my.cnf中添加:[mysqld]
log-slow-queries=/var/log/mysql/slow-query.log
long_query_time=2 # 超过2秒的查询视为慢查询
log-queries-not-using-indexes # 记录未使用索引的查询
SHOW命令:查看数据库状态(如SHOW STATUS LIKE 'Queries';查看总查询数)、系统变量(如SHOW VARIABLES LIKE 'innodb_buffer_pool_size';查看InnoDB缓冲池大小)、InnoDB状态(如SHOW ENGINE INNODB STATUS;查看InnoDB引擎运行状态)。EXPLAIN命令:分析查询执行计划,识别全表扫描、未使用索引等问题(如EXPLAIN SELECT * FROM users WHERE id = 1;)。swappiness值:减少系统使用swap分区的概率(swap会显著降低数据库性能)。编辑/etc/sysctl.conf,添加:vm.swappiness = 10 # 默认60%,设为10%表示系统仅在内存不足10%时使用swap
执行sysctl -p使配置生效。/etc/sysctl.conf,添加:vm.dirty_background_ratio = 5 # 后台进程开始刷新脏数据的阈值(内存脏数据占比)
vm.dirty_ratio = 10 # 系统强制刷新脏数据的阈值
执行sysctl -p使配置生效。innodb_buffer_pool_size:InnoDB存储引擎的核心参数,用于缓存数据页、索引页等,直接影响查询性能。建议设置为物理内存的50%-80%(专用数据库服务器),若数据量远小于内存,设为数据量的1.2倍即可。例如,32GB内存服务器可设为20G:[mysqld]
innodb_buffer_pool_size = 20G
innodb_log_buffer_size:InnoDB重做日志(Redo Log)的内存缓冲区,减少磁盘写入频率。写密集场景(如高并发插入)可调至64MB-256MB,默认16MB:innodb_log_buffer_size = 64M
key_buffer_size:MyISAM存储引擎的索引缓存(MyISAM已逐渐被淘汰,纯InnoDB场景可设为64MB-128MB):key_buffer_size = 128M
query_cache_size:查询结果缓存,适用于读多写少场景(如报表系统),但高并发写入场景会降低性能(需频繁清空缓存)。建议设置为64MB-256MB,或禁用(设为0):query_cache_type = 0 # 禁用查询缓存
query_cache_size = 0
innodb_flush_log_at_trx_commit:控制Redo Log的刷盘策略,平衡性能与数据安全性:
0:每秒刷盘一次,性能最高但风险最高(崩溃可能丢失未刷盘的事务,适合非核心业务);1(默认):事务提交时立即刷盘,最安全但性能最低(适合金融等强一致性场景);2:事务提交时写入OS缓存,每秒由OS刷盘,崩溃时可能丢失1秒数据,性能中等(适合一般业务)。innodb_flush_log_at_trx_commit = 2
max_connections:设置数据库允许的最大并发连接数,需根据应用并发访问情况调整(过多连接会导致资源耗尽)。例如,应用并发连接数为50,可设为100-200(预留缓冲):max_connections = 200
thread_cache_size:线程缓存大小,用于重用已经关闭的连接,减少连接建立和关闭的开销。建议设置为8-16:thread_cache_size = 16
slow_query_log:启用慢查询日志(已在准备工作中配置),帮助识别慢查询。log_bin:启用二进制日志(用于数据恢复和主从复制),建议开启:log_bin = /var/log/mysql/mysql-bin.log
expire_logs_days:设置二进制日志的过期时间(如7天),避免日志文件占用过多磁盘空间:expire_logs_days = 7
WHERE、JOIN、ORDER BY的列创建索引(如users表的id、email列)。避免在低基数列(如性别,只有男、女两种值)上创建索引(索引效果差)。SELECT id, name FROM users WHERE id = 1;,若(id)是索引,则无需回表查询name)。OPTIMIZE TABLE命令重建索引。SELECT *:只选择需要的列(如SELECT id, name FROM users;),减少数据传输量。JOIN操作:尽量将子查询转换为JOIN(JOIN通常比子查询更高效),避免多表关联过多(如超过3表关联需优化)。LIMIT限制返回结果:避免一次性返回大量数据(如SELECT * FROM users LIMIT 10;)。EXPLAIN命令分析查询执行计划,识别全表扫描、未使用索引等问题(如EXPLAIN SELECT * FROM users WHERE email = 'test@example.com';,若type为ALL,则表示全表扫描)。使用OPTIMIZE TABLE命令整理表碎片(删除数据后会产生碎片,导致表占用空间增大、查询变慢):
OPTIMIZE TABLE users;
对于InnoDB表,OPTIMIZE TABLE会重建表并整理碎片。
使用ANALYZE TABLE命令更新表的统计信息(MySQL优化器依赖统计信息选择执行计划,统计信息不准确会导致优化器选择低效的执行计划):
ANALYZE TABLE users;
定期归档旧数据(如将orders表中1年前的数据迁移到orders_archive表),减少表的大小(大表查询会消耗更多资源):
INSERT INTO orders_archive SELECT * FROM orders WHERE order_date < DATE_SUB(NOW(), INTERVAL 1 YEAR);
DELETE FROM orders WHERE order_date < DATE_SUB(NOW(), INTERVAL 1 YEAR);
htop:实时监控系统资源(CPU、内存、进程),安装命令:sudo yum install htop
MySQLTuner:评估数据库性能,提供优化建议(如调整缓冲池大小、连接数),使用方法:wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl
perl mysqltuner.pl
Percona Toolkit:高级数据库管理工具(如pt-query-digest分析慢查询日志、pt-table-checksum检查表一致性),安装命令:sudo yum install percona-toolkit
优化不是一劳永逸的,需根据业务增长(如数据量增加、并发量上升)持续调整参数(如逐步增加innodb_buffer_pool_size、调整max_connections)。每次仅修改1-2个参数,观察1-2周(避免激进调整引发稳定性问题)。