MySQL性能优化

慢查询日志

-- 开启慢查询日志 SET GLOBAL slow_query_log = ON; SET GLOBAL long_query_time = 1; -- 记录超过 1 秒的查询 SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log'; SET GLOBAL log_queries_not_using_indexes = ON; -- 用 pt-query-digest 分析 pt-query-digest /var/log/mysql/slow.log -- 查找最慢的查询 SELECT query_time, lock_time, rows_sent, rows_examined, sql_text FROM mysql.slow_log ORDER BY query_time DESC LIMIT 10;

EXPLAIN 输出解读

EXPLAIN SELECT * FROM orders o JOIN users u ON o.user_id = u.id WHERE o.status = 'pending' AND o.created_at > '2024-01-01'; -- 关键列: -- type: ALL(全表扫描)| ref | range | const(最好) -- key: 使用的索引(NULL = 未使用索引) -- rows: 预估扫描行数(越小越好) -- Extra: Using filesort / Using temporary(警告信号) -- 获取实际执行统计(MySQL 8.0+) EXPLAIN ANALYZE SELECT ...;

索引最佳实践

-- 组合索引——列顺序很重要! -- 适用于:WHERE status = 'active' AND user_id = 42 -- 适用于:WHERE status = 'active' -- 不适用:WHERE user_id = 42(必须从左开始) CREATE INDEX idx_status_user ON orders(status, user_id); -- 覆盖索引(包含所有查询列) CREATE INDEX idx_order_cover ON orders(user_id, status, created_at, total); -- 查找未使用的索引 SELECT * FROM sys.schema_unused_indexes;

关键配置参数

参数建议值影响
innodb_buffer_pool_sizeRAM 的 70-80%(16G 服务器设 8G)最关键——缓存数据和索引
innodb_log_file_size1-4 GB事务写入性能
innodb_flush_log_at_trx_commit2(性能优先)或 1(ACID 优先)写入持久性与性能权衡
max_connections150-500(使用连接池)防止资源耗尽
query_cache_type0(禁用——8.0 已废弃)避免缓存互斥竞争