拼图
109.2MB · 2026-02-28

有一种只有 DBA 才能体会的无聊。就是盯着运行的服务器,心想:肯定有什么地方可以优化。好消息是:确实有。
本文将详细 介绍几个能提升 MySQL 性能的变量,解释它们的重要性,以及调整这些变量何时能带来性能提升,何时又会悄然降低性能。本文主要针对 InnoDB 存储引擎。
在修改这个变量之前,请先查看以下内容:
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read%';
关键字段:
Innodb_buffer_pool_reads - 从磁盘的物理读取Innodb_buffer_pool_read_requests – 逻辑读取**经验法则:**如果 reads/read_requests > 1-2%,则说明您的缓冲池太小。
绘制 Innodb_buffer_pool_reads 随时间变化的曲线。健康的系统曲线应保持平稳或缓慢上升。出现类似城市天际线的峰值通常意味着内存压力过大或缓存冷却。
如果说 MySQL 性能方面有一颗璀璨的明珠,那非它莫属。
InnoDB 缓冲池会将表数据和索引缓存到内存中。从内存读取数据速度很快。从磁盘读取数据……简直是磨练意志。
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
如果你的数据库集群能够增加缓冲池,MySQL 会给你带来神奇的体验。但如果放不下,再多的查询优化也无济于事。
当内存容量增大时,这一点就显得尤为重要。
将缓冲区池拆分为多个实例,以减少内部互斥锁争用。
SHOW VARIABLES LIKE 'innodb_buffer_pool_instances';
并非越多越好。实例过多会浪费内存,并可能降低性能。
SHOW GLOBAL STATUS LIKE 'Innodb_log%';
请注意:
如果 Innodb_log_waits 不为零,则 Redo Log 日志对于您的写入速率来说太小。
绘制 Innodb_log_waits 每秒速率图。理想情况下,这条线应该紧贴零点,就像它害怕高度一样。
该变量控制 MySQL 处理写入密集型工作负载的平稳程度。
定义重做日志的大小。日志越大,检查点就越少,写入过程也越流畅。
SHOW VARIABLES LIKE 'innodb_log_file_size';
改变这一点需要重新开始。请做好相应计划,否则将承受未来值班时的自己带来的怒火。
SHOW GLOBAL STATUS LIKE 'Innodb_os_log_fsyncs';
从 1 切换到 2 通常 可以大幅减少 fsync 次数。
两条线重叠:
对于繁忙的系统而言,仅凭这张图表就足以让持怀疑态度的审计人员相信进行更改的合理性。
性能与耐用性,永恒的较量。
控制 Redo Log 日志刷新到磁盘的频率。
1 – 最安全,最慢(每次提交都刷新) 2 – 非常受欢迎的折衷方案 0 – 快速、高风险
SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit';
对于许多生产系统而言,配置属性 2 可以在可接受的风险范围内带来巨大的性能提升,尤其是在可靠的存储条件下。
这个变量决定了 MySQL 如何与磁盘通信。
控制 MySQL 是否使用操作系统缓存或绕过操作系统缓存。
innodb_flush_method=O_DIRECT
这样可以避免 MySQL 和操作系统页面缓存之间的双重缓冲。
某些叫旧的文件系统和内核表现可能有所不同,务必进行测试。
这不是性能调节的旋钮,而是控制耗损的旋钮。
限制并发客户端连接数。
每个连接都会消耗内存,连接过多会导致 MySQL 崩溃。
SHOW VARIABLES LIKE 'max_connections';
Threads_connectedSHOW GLOBAL STATUS LIKE 'Threads%';
关键字段:
如果 Threads_created / Connections 始终高于几个百分点,则说明您的缓存容量不足。
将线程数 Threads_created 作为计数器。一个健康的系统会呈现随时间推移而趋于平缓的曲线,而不是阶梯状曲线。
小改变,大胜利。
缓存线程,这样 MySQL 就不会不断地创建和销毁线程。
SHOW STATUS LIKE 'Threads_created';
如果该数值持续上升,则增加 thread_cache_size。
元数据比人们想象的更重要。
缓存打开的表和表结构,以避免重复访问文件系统。
Opened_tables 值高SHOW VARIABLES LIKE 'table_open_cache';
SHOW VARIABLES LIKE 'table_definition_cache';
SHOW GLOBAL STATUS LIKE 'Created_tmp%';
观察:
如果磁盘临时表超过总临时表的 5% 至 10%,则查询会溢出到磁盘。
堆积面积图:
磁盘使用率缓慢上升通常表明存在伪装成 OLTP 的报表查询。
基于磁盘的临时表是性能的隐形杀手。
限制内存临时表的大小。
将两者设置为相同的值:
tmp_table_size=256M
max_heap_table_size=256M
这有助于解决复杂的查询问题,但仍然需要修复错误的查询。
这不是一项绩效指标,而是一项绩效启示 。
你无法调整你看不见的东西。
slow_query_log=ON
long_query_time=1
这使得猜测变成了证据。
你不需要什么特殊的工具。这些工具就很好用:
performance_schemasys schema 视图黄金法则:永远绘制比率图表,而不是原始计数。
MySQL 的优化与其说是调整无穷无尽的参数,不如说是 了解压力点:
大多数性能提升都来自于 少数几个变量,而不是充满传奇色彩的复杂配置文件。
如果今天只能调整一项,那就调整缓冲池。如果只能调整两项,那就添加 Redo Log。其他一切都是精益求精。
如果你明天又觉得无聊,恭喜你,你正式成为一名数据库专家了。∎