CentOS上MySQL性能优化方法
硬件是数据库性能的基石,需优先满足以下需求:
MySQL的配置文件(/etc/my.cnf或/etc/mysql/my.cnf)是性能优化的关键,需根据硬件规格和业务场景调整以下核心参数:
innodb_buffer_pool_size:InnoDB存储引擎的核心缓存,用于缓存数据页、索引页、undo日志等,是最重要的性能参数。建议设置为物理内存的50%-70%(独占服务器);若数据量远小于内存,设为数据量的1.2倍(避免浪费)。示例:32GB内存服务器可设为20G。innodb_log_buffer_size:InnoDB重做日志(Redo Log)的内存缓冲区,减少磁盘写入频率。默认16MB,写密集场景(如高并发插入)可调至64MB-256MB(避免频繁刷盘)。key_buffer_size:MyISAM存储引擎的索引缓存(MyISAM已逐渐被淘汰,但仍需关注)。若使用MyISAM,设为内存的10%-20%;纯InnoDB场景可设为64MB-128MB(无需过多)。query_cache_size与query_cache_type:MySQL 8.0已移除查询缓存,5.7及以下版本需谨慎使用。写频繁场景建议关闭(query_cache_type=0,query_cache_size=0),避免缓存失效开销;读多写少场景可开启(query_cache_type=1,query_cache_size=128M-512M)。innodb_flush_log_at_trx_commit:控制Redo Log的刷盘策略,平衡性能与数据安全性。取值:0(每秒刷盘一次,性能最高但风险最高,崩溃可能丢失未刷盘的事务,适合非核心业务);2(事务提交时写入OS缓存,每秒由OS刷盘,崩溃时可能丢失1秒数据,性能中等);1(默认,事务提交时立即刷盘,最安全但性能最低,适合金融等强一致性场景)。innodb_flush_method:定义InnoDB与文件系统交互刷盘的方式,减少OS缓存二次拷贝。Linux系统优先设为O_DIRECT(直接写入磁盘,绕过OS缓存,减少内存占用)。innodb_file_per_table:开启后每个表单独生成.ibd文件(而非共享表空间ibdata1),便于单表管理、收缩空间和提高I/O效率。必须开启(设为1)。max_connections:允许的最大并发连接数,避免连接数不足导致“Too many connections”错误。建议结合服务器内存调整(每个连接约占用2MB-10MB内存),32GB内存服务器可设为1000-2000;同时设置max_user_connections限制单用户连接(防止恶意占用)。wait_timeout与interactive_timeout:控制空闲连接的超时时间,释放无效连接资源。默认8小时(28800秒),可缩短至300秒(5分钟)或600秒(减少连接池浪费)。innodb_lock_wait_timeout:事务等待行锁的超时时间,避免长事务阻塞。默认50秒,短事务场景可设为10-30秒(快速失败减少阻塞)。sort_buffer_size:排序操作的内存缓冲区,减少磁盘临时表排序。默认256KB,可设为1MB-8MB(根据单查询排序数据量,过大可能导致内存紧张)。read_buffer_size:表顺序扫描的缓冲区,提高顺序读取性能。默认128KB,可设为1MB-4MB(结合业务中顺序扫描的频率调整)。join_buffer_size:表连接时的缓存大小,优化多表连接性能。默认256KB,不宜过大(全局参数,每个连接都会分配),可设为1MB-4MB(结合业务中连接查询的复杂度调整)。PARTITION BY RANGE (YEAR(create_time))按年份分区)。archive_2024),减少主表的大小(降低查询和维护成本)。WHERE、JOIN、ORDER BY的列创建索引(如CREATE INDEX idx_user_id ON orders(user_id));避免在低基数列(如性别)上创建索引(索引效果差)。SELECT * FROM users WHERE id = 1会走主键索引,而SELECT * FROM users WHERE name LIKE '%张%'不会走索引);避免使用SELECT *,只选择需要的列(减少数据传输量)。EXPLAIN分析查询计划(查看是否走索引、是否有全表扫描),找出性能瓶颈;减少子查询(尽量将子查询转换为JOIN操作,如SELECT * FROM orders WHERE user_id IN (SELECT id FROM users WHERE status = 1)可改为SELECT o.* FROM orders o JOIN users u ON o.user_id = u.id WHERE u.status = 1);避免在WHERE子句中使用函数或表达式(如WHERE DATE(create_time) = '2025-10-01'会导致索引失效,可改为WHERE create_time >= '2025-10-01' AND create_time < '2025-10-02')。LIMIT子句限制返回的行数(如SELECT * FROM orders ORDER BY create_time DESC LIMIT 10),减少数据传输量。OPTIMIZE TABLE命令清理表碎片(如OPTIMIZE TABLE users),提高表的读写性能(适用于频繁更新的表)。ALTER TABLE users ENGINE=InnoDB),保持索引的高效性(索引碎片过多会影响查询性能)。ANALYZE TABLE命令更新表的统计信息(如ANALYZE TABLE orders),帮助优化器选择更优的执行计划(避免因统计信息不准确导致的低效查询)。slow_query_log = 1,long_query_time = 1),使用pt-query-digest或mysqlslowdump工具分析慢查询(找出执行时间长的查询),针对性优化。SELECT * FROM products WHERE id = 1的结果缓存到Redis,下次直接从Redis获取)。query_cache_type=1,query_cache_size=128M),但写频繁场景建议关闭(避免缓存失效开销);MySQL 8.0已移除查询缓存。MySQLTuner工具分析数据库性能(如wget mysqltuner.pl && perl mysqltuner.pl),提供内存、连接、索引等方面的优化建议(适合新手快速定位问题)。pt-query-digest分析慢查询日志(如pt-query-digest /var/log/mysql/slow.log),找出最耗时的查询;使用pt-index-usage分析索引使用情况(如pt-index-usage /var/log/mysql/mysql.log),找出未使用的索引(减少不必要的索引)。performance_schema(performance_schema=1),监控数据库的性能指标(如锁等待、I/O延迟、SQL执行时间),帮助定位性能瓶颈(如SELECT * FROM performance_schema.events_statements_summary_by_digest ORDER BY SUM_TIMER_WAIT DESC LIMIT 10查看最耗时的SQL)。