MySQL 8.0 彻底移除查询缓存,query_cache_type 已删除;重复 SQL 必须重解析执行,预处理语句和 InnoDB 缓冲池才是实际缓存机制;应用层应主动用 Redis 等实现可控缓存。
MySQL 8.0 默认不启用查询缓存,
已被移除
MySQL 5.7 及更早版本支持的查询缓存(Query Cache)在 8.0 中彻底删除。这意味着无论你执行多少次相同的
语句,MySQL 都不会从内存中直接返回结果——它必须走完整的解析、优化、执行流程。如果你还在用 8.0+ 并期待“SQL 缓存自动生效”,那这个预期本身就是错的。
常见误判现象:
在 8.0 中查不到任何变量;
配置文件
里写了
会启动失败或静默忽略。
每次执行 SQL 确实都会重新解析,但有预处理语句(
)和连接级缓存可缓解
MySQL 对普通文本协议(text protocol)的 SQL,每次请求都做词法分析 → 语法分析 → 语义检查 → 生成执行计划。即使语句完全相同,只要没复用预处理对象,就无法跳过解析阶段。
后,多次
可复用解析结果和执行计划
客户端驱动(如 Python 的
、Java 的
)默认启用预处理,但需确认是否实际走 binary protocol
注意:表结构变更(如加索引、改字段类型)会导致已缓存的执行计划失效,下次仍需重编译
真正起效的“缓存”在服务端是 InnoDB 缓冲池,不是 SQL 层
所谓“重复查询变快”,绝大多数情况是因为第二次执行时所需的数据页已在
中,避免了磁盘 I/O。这和 SQL 文本是否相同无关,只和访问的数据块有关。
go语言参考手册 中文CHM版
Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。本文给大家带来Go参考手册,需要的可以来下载! Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。 Go 语言特色 简洁、快速、安全 并行、有趣、开源 内存管理、v数组安全、编译
下载
验证方式:
第一次执行后查
和
,差值越大说明缓存命中越差
执行
可粗略看缓冲池使用量
如果
远小于数据总大小,反复执行同一条 SQL 依然可能频繁换页、表现不稳定
应用层该怎么做:别依赖 MySQL 自动缓存,自己控制粒度
想避免重复解析 + 执行开销,不能靠等 MySQL “聪明起来”。得明确谁负责缓存、缓存什么、何时失效。
高频读、低频写的数据(如配置表、省份列表),用 Redis 缓存完整结果集,键名可带版本号或
用 ORM 时慎用动态拼接 SQL,优先走参数化查询 + 预编译路径(如 Djan
go
的
不如
可优化)
监控慢日志里反复出现的相同
,不是加索引就能解决——要判断是否该由应用兜底缓存
复杂点往往不在 SQL 是否被“缓存”,而在于你是否清楚当前这行语句,到底是在和网络、解析器、锁管理器、还是磁盘打交道。
query_cache_typeSELECTSHOW VARIABLES LIKE 'query_cache%'query_cache_type=1PREPAREPREPARE stmt FROM 'SELECT * FROM users WHERE id = ?'EXECUTE stmt USING @idpymysqlPreparedStatementinnodb_buffer_poolSHOW STATUS LIKE 'Innodb_buffer_pool_read_requests'Innodb_buffer_pool_readsSELECT COUNT(*) FROM information_schema.INNODB_BUFFER_PAGEinnodb_buffer_pool_sizeTTLraw()filter(id__in=[...])SQL_TEXTSELECT query_time, lock_time, rows_sent, sql_text
FROM mysql.slow_log
WHERE sql_text LIKE 'SELECT % FROM orders WHERE user_id = %'
ORDER BY start_time DESC LIMIT 5;