mysql 5.7+ 中 sql_no_cache 已被移除,仅静默忽略而不报错;其失效主因是 query_cache_type 默认关闭且查询缓存模块在 8.0 彻底删除。
mysql 5.7 及以后版本中,sql_no_cache 已被移除,对查询加该提示不会报错但完全无效;真正影响执行计划和缓存行为的是查询是否命中 query_cache(已弃用)或更底层的 innodb 缓冲池与 mysql server 层的 prepared statement 缓存逻辑。
为什么 SQL_NO_CACHE 看起来“没反应”
这是最常被误解的一点:在 MySQL 5.7+ 中,即使你写 SELECT SQL_NO_CACHE * FROM t,MySQL 也会安静地忽略它——既不报错,也不起作用。这是因为 query_cache_type 默认为 OFF,且整个查询缓存模块已在 8.0 中彻底删除。
-
SQL_NO_CACHE和SQL_CACHE只对启用了query_cache_type=1的旧版本(如 5.6)有效 - 启用 query cache 后,它只缓存**完全一致的文本查询**(大小写、空格、注释都必须相同),实际生产中极易失效
- InnoDB 的
buffer_pool缓存的是数据页和索引页,和SQL_NO_CACHE无关;它不会“缓存结果”,而是缓存物理块 - 客户端驱动(如 mysql-client、JDBC)可能自带语句缓存,那才是你真正需要关的地方
怎么确认当前查询是否走了查询缓存(仅限 5.6 或手动开启 query_cache 的 5.7)
别靠猜,用系统状态变量直接验证:
- 执行前先查:
SHOW STATUS LIKE 'Qcache_hits'和SHOW STATUS LIKE 'Qcache_inserts' - 跑一次你的
SELECT SQL_NO_CACHE ...,再查一次这两个值——如果Qcache_inserts增了,说明它被缓存了(即你没加对或 server 没认) - 如果加了
SQL_NO_CACHE后Qcache_hits没变,但Com_select增了,说明查询执行了,但没进 query cache(符合预期) - 注意:
Qcache_lowmem_prunes高意味着缓存频繁被挤掉,这时开 query cache 反而拖慢性能
如何真正绕过各种缓存看真实执行计划和耗时
想测“纯 SQL 执行效率”,要同时避开 query cache、buffer pool 预热、操作系统 page cache 三重干扰:
- 禁用 query cache(推荐):
SET SESSION query_cache_type = OFF(会话级,不影响别人) - 清空 buffer pool(需 SUPER 权限):
SET GLOBAL innodb_buffer_pool_dump_now = ON→SET GLOBAL innodb_buffer_pool_load_now = OFF→ 再重启 mysqld 更彻底(测试环境可用) - 每次测前用
SELECT SLEEP(0.1)+FLUSH STATUS重置计数器,避免复用上次统计 - 用
EXPLAIN FORMAT=JSON查执行计划,重点关注used_columns、filtered、rows_examined_per_scan字段,不是只看type和key - 用
SELECT BENCHMARK(10000, your_expression)测表达式级开销,比单次SELECT更稳定
容易被忽略的关键点
很多人花半天调 SQL_NO_CACHE,却忘了真正决定性能的是索引选择、JOIN 顺序、统计信息是否陈旧,以及是否用了 pt-query-digest 这类工具看真实慢日志分布。
如果你在监控里看到某条语句 Rows_examined 是 Rows_sent 的上百倍,那加不加 SQL_NO_CACHE 都没意义——先看执行计划里有没有全表扫描,再检查 ANALYZE TABLE 是否做过。











