MySQL查询缓存

01.MySQL查询缓存

1、概述

  • 为了提高完全相同的查询语句的响应速度,MySQL Server 会对查询语句进行 Hash 计算得到一个 Hash 值
  • MySQL Server 不会对 SQL 做任何处理,SQL 必须完全一致 Hash 值才会一样
  • 得到 Hash 值之后,通过该 Hash 值到查询缓存中匹配该查询的结果
  • MySQL Server 会对查询语句进行 Hash 计算得到一个 Hash 值
  • 再次查询如果 Hash 值完全一样,就算匹配了缓存
  • 如果匹配(命中),则将查询的结果集直接返回给客户端不必再解析、执行查询
  • 如果没有匹配(未命中),则将 Hash 值和结果集保存在查询缓存中,以便以后使用

2、缓存规则

  • 查询缓存会将查询语句和结果集保存到内存(key 是查询语句,value 是查询的结果集
  • 缓存的结果是通过 sessions 共享的,所以一个 client 查询的缓存结果,另一个 client 也可以使用
  • SQL 必须完全一致才会导致查询缓存命中(大小写、空格、使用的数据库、协议版本、字符集等必须一致)
  • 不缓存查询中的子查询结果集,仅缓存查询最终结果集
  • 不确定的函数将永远不会被缓存, 比如 now()curdate()last_insert_id()rand() 等
  • 不缓存产生告警(Warnings)的查询
  • 太大的结果集不会被缓存 (< query_cache_limit)
  • 如果查询中包含任何用户自定义函数、存储函数、用户变量、临时表、MySQL 库中的系统表,其查询结果也不会被缓存
  • 缓存建立之后,MySQL 的查询缓存系统会跟踪查询中涉及的每张表
  • 如果这些表(数据或结构)发生变化,那么和这张表相关的所有缓存数据都将失效
  • MySQL 缓存在分库分表环境下是不起作用的
  • 不缓存使用 SQL_NO_CACHE 的查询

3、缓存机制中的内存管理

  • 查询缓存是完全存储在内存中的,所以在配置和使用它之前,我们需要先了解它是如何使用内存的

  • MySQL 查询缓存使用内存池技术,自己管理内存释放和分配,而不是通过操作系统

  • 内存池使用的基本单位是变长的 block, 用来存储类型、大小、数据等信息

  • 一个结果集的缓存通过链表把这些 block 串起来

  • block 最短长度为 query_cache_min_res_unit

  • 当服务器启动的时候,会初始化缓存需要的内存,是一个完整的空闲块

  • 当查询结果需要缓存的时候,先从空闲块中申请一个数据块为参数 query_cache_min_res_unit 配置的空间

  • 即使缓存数据很小,申请数据块也是这个,因为查询开始返回结果的时候就分配空间,此时无法预知结果多大

  • 分配内存块需要先锁住空间块,所以操作很慢,MySQL 会尽量避免这个操作,选择尽可能小的内存块

  • 如果不够,继续申请,如果存储完时有空余则释放多余的

  • 但是如果并发的操作,余下的需要回收的空间很小,小于 query_cache_min_res_unit,不能再次被使用,就会产生碎片

4、查询缓存的优缺点

优点

  • 查询缓存的查询,发生在 MySQL 接收到客户端的查询请求、查询权限验证之后和查询 SQL 解析之前
  • 不需要发生任何存储引擎的交互
  • 由于查询缓存是基于内存的,效率非常高

缺点

  • 对每条 sql 都需要 hash计算,会带来一定开销
  • 如果表的变更比较频繁缓存的失效率非常高
  • 查询语句不同,但查询结果相同的查询都会被缓存,这样便会造成内存资源的过度消耗
  • 查询语句的字符大小写、空格或者注释的不同,查询缓存都会认为是不同的查询(因为他们的 Hash 值会不同)
  • 相关系统变量设置不合理会造成大量的内存碎片,这样便会导致查询缓存频繁清理内存

5、总结

MySQL 中的查询缓存虽然能够提升数据库的查询性能,但是查询同时也带来了额外的开销,每次查询后都要做一次缓存操作,失效后还要销毁。

  • 查询缓存是一个适用较少情况的缓存机制

  • 如果你的应用对数据库的更新很少,那么查询缓存将会作用显著

  • 比较典型的如博客系统,一般博客更新相对较慢,数据表相对稳定不变,这时候查询缓存的作用会比较明显

  • 简单总结一下查询缓存的适用场景

    • 表数据修改不频繁、数据较静态

    • 查询(Select)重复度高

    • 查询结果集小于 1 MB

  • 简单总结一下查询缓存不适用的场景

    • 表中的数据、表结构或者索引变动频繁

    • 重复的查询很少

    • 查询的结果集很大

根据我们的经验,在高并发压力环境中查询缓存会导致系统性能的下降,甚至僵死

如果你一 定要使用查询缓存,那么不要设置太大内存,而且只有在明确收益的时候才使用(数据库内容修改次数较少)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不做大哥好多年xw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值