MySQL查询缓存详解
大约 4 分钟
MySQL查询缓存详解
1. MySQL 查询缓存介绍
1.1 什么是查询缓存?
MySQL 查询缓存(Query Cache)是将 SELECT 查询结果 存储在内存中,以便相同的查询可以直接返回缓存结果,而无需再次执行。
- 缓存内容:查询的结果集。
- 核心作用:加速查询性能,减少数据库的计算开销。
1.2 查询缓存适用的场景
- 高频查询:相同的查询语句多次执行且数据变化较少。
- 只读场景:例如报表系统、查询频繁更新少的业务场景。
2. MySQL 查询缓存管理和配置
2.1 查询缓存的相关参数
query_cache_size:
- 设置查询缓存的总大小。
- 示例:
SET GLOBAL query_cache_size = 1048576;(1MB 缓存)
query_cache_type:
控制查询缓存是否启用。
0(OFF):关闭查询缓存。1(ON):默认开启查询缓存。2(DEMAND):按需缓存,仅当查询语句中显式指定SQL_CACHE时缓存。
示例:
SET GLOBAL query_cache_type = 1;
query_cache_limit:
- 指定单个查询可以缓存的最大结果集大小。
- 示例:
SET GLOBAL query_cache_limit = 1048576;(1MB)
query_cache_min_res_unit:
- 缓存块的最小分配单位。默认为 4096 字节。
2.2 查询缓存的开启与禁用
查看查询缓存状态
SHOW VARIABLES LIKE 'query_cache%';开启查询缓存
SET GLOBAL query_cache_size = 1048576; -- 设置查询缓存大小 SET GLOBAL query_cache_type = 1; -- 开启查询缓存禁用查询缓存
SET GLOBAL query_cache_type = 0; -- 禁用查询缓存
2.3 显式使用或跳过查询缓存
使用缓存:
SELECT SQL_CACHE * FROM users WHERE id = 1;跳过缓存:
SELECT SQL_NO_CACHE * FROM users WHERE id = 1;
3. MySQL 缓存机制
3.1 查询缓存的工作流程
检查缓存:
- 查询语句在执行前,先检查是否命中查询缓存。
- 如果命中,直接返回结果;否则进入下一步。
执行查询:
- 如果缓存未命中,MySQL 执行查询语句并生成结果集。
存储缓存:
- 查询结果集存入缓存区域,供后续相同查询使用。
3.2 查询缓存规则
语句完全相同:
- 只有当查询语句完全相同时(包括大小写、空格),才会命中缓存。
- 示例:
SELECT * FROM users WHERE id = 1; -- 可命中缓存 SELECT * FROM users WHERE id=1; -- 无法命中
表未更新:
- 只要查询涉及的表发生了更新、插入或删除,相关缓存会立即失效。
与用户权限相关:
- 如果查询涉及用户权限,MySQL 会为每个用户缓存单独的结果集。
无法缓存的情况:
- 查询包含非确定性函数(如
NOW()、RAND())。 - 查询包含用户变量或临时表。
- 查询包含
LOCK或FOR UPDATE。
- 查询包含非确定性函数(如
4. 缓存机制中的内存管理
内存分配策略:
- 查询缓存分为多个内存块,每个块存储一个查询结果。
- 如果一个查询的结果集大小超过
query_cache_limit,则该查询不会被缓存。
内存清理:
- 当缓存满时,MySQL 会清除不常使用的缓存结果(LRU 策略)。
缓存碎片问题:
- 缓存碎片会导致内存利用率下降,影响性能。
- 通过
FLUSH QUERY CACHE清理碎片并整理内存。
5. MySQL 查询缓存的优缺点
5.1 优点
- 加速查询:
- 对于相同的查询,直接返回缓存结果,避免重复执行。
- 减少 I/O:
- 缓存结果存储在内存中,减少磁盘访问。
- 降低 CPU 负载:
- 重复查询不需要再次解析、优化和执行。
5.2 缺点
- 缓存失效频繁:
- 表数据更新会导致相关缓存失效,不适合频繁写入场景。
- 缓存命中条件严格:
- 查询语句必须完全相同,稍有不同就无法命中。
- 额外开销:
- 需要维护查询缓存,带来内存和 CPU 开销。
- 缓存碎片问题:
- 内存碎片会影响缓存的效率,需要定期清理。
6. MySQL 查询缓存对性能的影响
6.1 适用场景
- 高频相同查询,低写入频率:
- 如报表查询、查询用户统计等。
6.2 不适用场景
- 频繁更新的表:
- 写操作会使缓存失效,频繁更新导致缓存无意义。
6.3 性能优化建议
- 按需开启缓存:
- 使用
query_cache_type = DEMAND,仅对需要的查询启用缓存。
- 使用
- 合理配置参数:
- 根据查询特点调整
query_cache_size和query_cache_limit。
- 根据查询特点调整
- 避免缓存碎片:
- 定期使用
FLUSH QUERY CACHE清理碎片。
- 定期使用
7. 总结
查询缓存的核心目标:
- 提高查询性能,减少重复查询带来的开销。
关键点:
- 查询语句必须完全相同才能命中缓存。
- 表的更新操作会使相关缓存失效。
注意事项:
- 查询缓存已在 MySQL 8.0 中被废弃,建议根据业务场景合理使用或选择替代方案(如应用层缓存)。
