MySQL 8.0版本正式移除了查询缓存功能,这是很多用户从5.7版本升级后遇到的第一个性能相关的问题。原本依赖查询缓存提升高频重复查询效率的场景,在升级后会出现查询响应时间变长的情况,需要从其他维度进行优化调整。

查询缓存失效的原因说明
MySQL官方在8.0版本中彻底删除了查询缓存相关的所有代码,原因是查询缓存的维护成本很高,且在高并发写入场景下,查询缓存的失效机制会导致大量不必要的缓存清理操作,反而会降低整体性能。因此升级到8.0后,原本的query_cache_type、query_cache_size等参数都会失效,相关的缓存功能也不再可用。
SQL层面的优化方案
优化重复查询逻辑
对于原本依赖查询缓存的高频重复查询,首先可以检查SQL语句本身是否存在可优化的空间。比如避免select * 语句,只查询需要的字段,减少数据传输和解析的开销。
以下是一个优化前后的SQL示例:
-- 优化前,查询所有字段 SELECT * FROM user_info WHERE user_id = 1001; -- 优化后,只查询需要的字段 SELECT user_name, user_age, user_email FROM user_info WHERE user_id = 1001;
建立合适的索引
针对高频查询的过滤条件、排序字段、关联字段建立合适的索引,提升查询的检索效率。需要注意的是索引不是越多越好,过多的索引会影响写入性能,需要结合业务场景权衡。
创建索引的示例代码如下:
-- 为user_info表的user_id字段创建普通索引 CREATE INDEX idx_user_id ON user_info(user_id); -- 为订单表的用户ID和创建时间创建联合索引,适合按用户查询最近订单的场景 CREATE INDEX idx_user_create_time ON order_info(user_id, create_time);
使用查询重写插件
MySQL 8.0提供了查询重写插件,可以对输入的SQL语句进行重写,比如把复杂的重复查询重写为更高效的执行方式,或者统一查询的写法减少解析差异。
启用查询重写插件的步骤如下:
-- 安装查询重写插件
INSTALL PLUGIN rewrite_plugin SONAME 'rewrite_plugin.so';
-- 查看插件是否安装成功
SHOW PLUGINS;
-- 添加重写规则,把查询user表所有数据的语句重写为只查询必要字段
INSERT INTO query_rewrite.rewrite_rules(pattern, replacement, pattern_database) VALUES (
'SELECT * FROM user',
'SELECT id, name FROM user',
'test_db'
);
-- 刷新规则使生效
CALL query_rewrite.flush_rewrite_rules();
内存配置优化方案
调整InnoDB缓冲池大小
InnoDB缓冲池是MySQL中最重要的内存区域,用于缓存表数据和索引数据,相当于替代了部分查询缓存的作用。可以适当调大innodb_buffer_pool_size参数,让更多热数据留在内存中。
查看和调整该参数的代码如下:
-- 查看当前InnoDB缓冲池大小,单位是字节 SHOW VARIABLES LIKE 'innodb_buffer_pool_size'; -- 在线调整缓冲池大小,设置为系统内存的60%左右比较合适,比如8G内存设置为5G SET GLOBAL innodb_buffer_pool_size = 5368709120; -- 永久生效需要修改my.cnf配置文件 -- [mysqld] -- innodb_buffer_pool_size = 5G
调整排序和连接相关内存参数
对于需要排序、分组或者多表关联的查询,可以适当调大sort_buffer_size、join_buffer_size等参数,减少临时表落盘的情况,提升查询效率。
相关参数调整示例:
-- 查看当前排序缓冲区大小 SHOW VARIABLES LIKE 'sort_buffer_size'; -- 调整排序缓冲区为4M,注意该参数是会话级参数,不要设置过大避免内存溢出 SET GLOBAL sort_buffer_size = 4194304; -- 调整连接缓冲区为2M SET GLOBAL join_buffer_size = 2097152;
优化查询缓存相关参数的替代配置
虽然查询缓存已经移除,但是可以调整table_open_cache、thread_cache_size等参数,减少表打开和线程创建的开销,间接提升查询的响应速度。
| 参数名称 | 作用说明 | 建议配置值 |
|---|---|---|
| table_open_cache | 缓存表文件描述符的数量,减少表打开的开销 | 根据数据库中表的数量设置,一般设置为2000-4000 |
| thread_cache_size | 缓存空闲线程的数量,减少线程创建销毁的开销 | 设置为服务器CPU核心数的2-3倍 |
| read_buffer_size | 顺序读取表数据时的缓冲区大小 | 设置为1-2M即可 |
优化后的效果验证
完成上述优化后,可以通过SHOW GLOBAL STATUS命令查看相关的状态指标,比如Innodb_buffer_pool_read_requests和Innodb_buffer_pool_reads,计算缓冲池的命中率,命中率越高说明内存配置越合理。同时可以对比优化前后相同查询的响应时间,确认优化效果。
查询缓冲池命中率的示例:
-- 查看缓冲池读取请求数和磁盘读取数 SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read_requests'; SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_reads'; -- 命中率计算公式:(read_requests - reads) / read_requests * 100% -- 一般命中率需要保持在99%以上