跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

mysql执行SQL是否每次都会重新解析_SQL缓存机制解析

MySQL 8.0 彻底移除查询缓存,query_cache_type 已删除;重复 SQL 必须重解析执行,预处理语句和 InnoDB 缓冲池才是实际缓存机制;应用层应主动用 Redis 等实现可控缓存。 MySQL 8.0 默认不启用查询缓存,
query_cache_type
已被移除 MySQL 5.7 及更早版本支持的查询缓存(Query Cache)在 8.0 中彻底删除。这意味着无论你执行多少次相同的
SELECT
语句,MySQL 都不会从内存中直接返回结果——它必须走完整的解析、优化、执行流程。如果你还在用 8.0+ 并期待“SQL 缓存自动生效”,那这个预期本身就是错的。 常见误判现象:
SHOW VARIABLES LIKE 'query_cache%'
在 8.0 中查不到任何变量; 配置文件 里写了
query_cache_type=1
会启动失败或静默忽略。 每次执行 SQL 确实都会重新解析,但有预处理语句(
PREPARE
)和连接级缓存可缓解 MySQL 对普通文本协议(text protocol)的 SQL,每次请求都做词法分析 → 语法分析 → 语义检查 → 生成执行计划。即使语句完全相同,只要没复用预处理对象,就无法跳过解析阶段。
PREPARE stmt FROM 'SELECT * FROM users WHERE id = ?'
后,多次
EXECUTE stmt USING @id
可复用解析结果和执行计划 客户端驱动(如 Python 的
pymysql
、Java 的
PreparedStatement
)默认启用预处理,但需确认是否实际走 binary protocol 注意:表结构变更(如加索引、改字段类型)会导致已缓存的执行计划失效,下次仍需重编译 真正起效的“缓存”在服务端是 InnoDB 缓冲池,不是 SQL 层 所谓“重复查询变快”,绝大多数情况是因为第二次执行时所需的数据页已在
innodb_buffer_pool
中,避免了磁盘 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数组安全、编译 下载 验证方式: 第一次执行后查
SHOW STATUS LIKE 'Innodb_buffer_pool_read_requests'
和
Innodb_buffer_pool_reads
,差值越大说明缓存命中越差 执行
SELECT COUNT(*) FROM information_schema.INNODB_BUFFER_PAGE
可粗略看缓冲池使用量 如果
innodb_buffer_pool_size
远小于数据总大小,反复执行同一条 SQL 依然可能频繁换页、表现不稳定 应用层该怎么做:别依赖 MySQL 自动缓存,自己控制粒度 想避免重复解析 + 执行开销,不能靠等 MySQL “聪明起来”。得明确谁负责缓存、缓存什么、何时失效。 高频读、低频写的数据(如配置表、省份列表),用 Redis 缓存完整结果集,键名可带版本号或
TTL
用 ORM 时慎用动态拼接 SQL,优先走参数化查询 + 预编译路径(如 Djan go 的
raw()
不如
filter(id__in=[...])
可优化) 监控慢日志里反复出现的相同
SQL_TEXT
,不是加索引就能解决——要判断是否该由应用兜底缓存
SELECT 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;
复杂点往往不在 SQL 是否被“缓存”,而在于你是否清楚当前这行语句,到底是在和网络、解析器、锁管理器、还是磁盘打交道。

相关文章