MySQL 优化
慢查询日志
启用慢查询日志以找到需要优化的查询。
-- Enable slow query log
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
SET GLOBAL long_query_time = 1; -- log queries > 1 second
SET GLOBAL log_queries_not_using_indexes = 'ON';
-- Check current settings
SHOW VARIABLES LIKE 'slow_query%';
SHOW VARIABLES LIKE 'long_query_time';
-- Analyze slow query log with mysqldumpslow
-- mysqldumpslow -s t -t 10 /var/log/mysql/slow.log
-- -s t: sort by total time; -t 10: top 10 queries
-- Or use pt-query-digest (Percona Toolkit)
-- pt-query-digest /var/log/mysql/slow.log
ANALYZE TABLE 与统计信息
-- Update table statistics (helps optimizer)
ANALYZE TABLE orders, products, users;
-- Check table status
SHOW TABLE STATUS LIKE 'orders'\G
-- InnoDB statistics settings
SET GLOBAL innodb_stats_auto_recalc = ON;
SET GLOBAL innodb_stats_persistent = ON;
SET GLOBAL innodb_stats_persistent_sample_pages = 20;
-- Force statistics update for a table
ALTER TABLE large_table ENGINE=InnoDB; -- rebuilds + recalculates
-- Check index statistics
SELECT * FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = 'mydb' AND TABLE_NAME = 'orders';
InnoDB 缓冲池调优
-- Set buffer pool size (typically 70-80% of RAM)
SET GLOBAL innodb_buffer_pool_size = 4294967296; -- 4 GB
-- Multiple buffer pool instances (for servers > 1 GB pool)
SET GLOBAL innodb_buffer_pool_instances = 4;
-- Check buffer pool hit rate
SELECT
(1 - (phy_reads / (buf_reads + 1))) * 100 AS hit_rate_pct
FROM (
SELECT
SUM(VARIABLE_VALUE) AS buf_reads
FROM performance_schema.global_status
WHERE VARIABLE_NAME = 'Innodb_buffer_pool_read_requests'
) r,
(
SELECT SUM(VARIABLE_VALUE) AS phy_reads
FROM performance_schema.global_status
WHERE VARIABLE_NAME = 'Innodb_buffer_pool_reads'
) p;
-- Show buffer pool status
SHOW STATUS LIKE 'Innodb_buffer_pool%';
分区裁剪
分区裁剪跳过不相关的分区,大幅减少扫描行数。
-- RANGE partition by year
CREATE TABLE events (
id INT NOT NULL,
event_dt DATE NOT NULL,
payload TEXT
) PARTITION BY RANGE (YEAR(event_dt)) (
PARTITION p2022 VALUES LESS THAN (2023),
PARTITION p2023 VALUES LESS THAN (2024),
PARTITION p2024 VALUES LESS THAN (2025),
PARTITION pmax VALUES LESS THAN MAXVALUE
);
-- Pruning in action: only scans p2024
SELECT * FROM events WHERE event_dt BETWEEN '2024-01-01' AND '2024-12-31';
-- Verify pruning with EXPLAIN PARTITIONS
EXPLAIN SELECT * FROM events WHERE YEAR(event_dt) = 2024;
-- partitions column shows which partitions are accessed
-- Manage partitions
ALTER TABLE events ADD PARTITION (PARTITION p2025 VALUES LESS THAN (2026));
ALTER TABLE events DROP PARTITION p2022;
连接池与关键变量
-- Key connection variables
SHOW VARIABLES LIKE 'max_connections'; -- default 151
SET GLOBAL max_connections = 500;
SHOW VARIABLES LIKE 'thread_cache_size'; -- reuse threads
SET GLOBAL thread_cache_size = 50;
SHOW STATUS LIKE 'Threads_connected';
SHOW STATUS LIKE 'Connection_errors%';
-- ProxySQL connection pool example config (proxysql.cfg)
-- mysql_servers = ( { address="127.0.0.1" port=3306 max_connections=200 } )
-- mysql_users = ( { username="app" default_hostgroup=0 } )
-- Important InnoDB I/O settings
SET GLOBAL innodb_flush_log_at_trx_commit = 1; -- safest (fsync per commit)
SET GLOBAL innodb_io_capacity = 2000; -- for SSDs
SET GLOBAL innodb_read_io_threads = 4;
SET GLOBAL innodb_write_io_threads = 4;
| 变量 | 推荐值 | 说明 |
|---|---|---|
innodb_buffer_pool_size | 70–80% RAM | 最重要的 InnoDB 设置 |
innodb_log_file_size | 256M–1G | 越大检查点刷新越少 |
max_connections | 200–500 | 使用连接池保持在此范围内 |
query_cache_type | 0 (OFF) | 8.0 中已废弃,使用应用层缓存 |