MySQL缓存机制

article/2025/10/6 8:40:48

1. MySQL缓存简介

  1. MySQL缓存机制说明
    MySQL缓存机制即缓存sql 文本及缓存结果,用KV形式保存再服务器内存中,如果运行相同的sql,服务器直接从缓存中去获取结果,不需要再去解析、优化、执行sql

  2. MySQL缓存失效
    在表的结构或数据发生改变时,查询缓存中的数据不再有效,查询缓存值的相关条目将被清空
    INSERT、UPDATE、 DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE会导致缓存数据失效

  3. 使用场景
    对于频繁更新的表,查询缓存不合适
    对于一些不变的数据且有大量相同sql查询的表,查询缓存可以大大提高查询的性能

2. 命中条件:

缓存的数据结构是hash表
以SQL、数据库名和客户端协议等作为KEY
在判断命中前,MySQL不会解析SQL,而是使用SQL去查询缓存,SQL上的任何字符的不同,如空格、注释等都会导致缓存不命中
如果查询有不确定的数据,如like now()、current_date(),那么查询完成后结果都不会被缓存

3. 工作流程:

服务器接收SQL,以SQL和一些其他条件为key查找缓存表
如果缓存命中,则直接返回缓存
如果缓存没有命中,则执行SQL查询,包括SQL解析、优化等。
执行完SQL查询结果以后,将SQL查询结果写入缓存表

4. 缓存失败:

当某个表正在写入数据,则这个表的缓存将会处于失效状态
在InnoDB中,如果某个事务修改了表,则这个表的缓存在事务提交前都会处于失效状态,即在事务提交前,这个表的相关查询都无法被缓存

5. 缓存的内存管理:

MySQL缓存机制会在内存中开辟一块内存(query_cache_size)区来维护缓存数据,其中大概有40K的空间是用来维护缓存数据的元数据的,例如空间内存、数据表和查询结果的映射,SQL和查询结果的映射。
MySQL缓存机制将大内存块分为小内存块(query_cache_min_res_unit),每个小块中存储自身的类型、大小和查询结果数据,还有前后内存块的指针。
MySQL缓存机制会在SQL查询开始(还未得到结果)时就去申请一块内存空间,所以即使缓存数据没有达到这个大小也需要占用申请的内存块空间(like linux filesystem’s block)。如果超出申请内存块的大小,则需要再申请一个内存块。当查询完成发现申请的内存有富余,则会将富余的内存空间释放掉,因而可能会造成内存碎片。
在这里插入图片描述

6. 缓存的使用时机:

  1. 通过缓存命中率判断
    缓存命中率 = 缓存命中次数 (Qcache_hits) / 查询次数 (Com_select)

  2. 通过缓存写入率判断
    写入率 = 缓存写入次数 (Qcache_inserts) / 查询次数 (Qcache_inserts)

  3. 通过命中-写入率判断
    比率 = 命中次数 (Qcache_hits) / 写入次数 (Qcache_inserts),

高性能MySQL中称之为比较能反映性能提升的指数,一般来说达到3:1则算是查询缓存有效,而最好能够达到10:1

7. 缓存参数配置:

  1. 查看缓存相关配置
    SHOW VARIABLES LIKE ‘%query_cache%’;
  2. query_cache_type
    是否打开缓存,可选参数有:
  • OFF(0):关闭 ,不使用查询缓存
  • ON(1):总是打开 ,始终使用查询缓存
  • DEMAND(2):按需使用查询缓存,只有明确写了SQL_CACHE的查询才会写入缓存
    如果query_cache_type为1而又不想利用查询缓存中的数据,可以用下面的SQL:
  • SELECT SQL_NO_CACHE * FROM my_table WHERE condition;
    如果值为2,要使用缓存的话,需要使用SQL_CACHE开关参数:
  • SELECT SQL_CACHE * FROM my_table WHERE condition;
  1. query_cache_size
    缓存使用的总内存空间大小,单位是字节,这个值必须是1024的整数倍;否则MySQL实际分配可能跟这个数值不同(感觉这个应该跟文件系统的blcok大小有关)
    默认情况下query_cache_size为0,表示为查询缓存预留的内存为0,则无法使用查询缓存
    设置query_cache_size的值
  • SET GLOBAL query_cache_size = 134217728; – 注意值如果设得太小不会生效
  1. query_cache_min_res_unit
    分配内存块时的最小单位大小
  2. query_cache_limit
    MySQL能够缓存的最大结果,如果超出,则增加 Qcache_not_cached的值,并删除查询结果
  3. query_cache_wlock_invalidate
    如果某个数据表被锁住,是否仍然从缓存中返回数据,默认是OFF,表示仍然可以返回
  4. GLOBAL STATUS 中关于缓存的参数解释
    Qcache_free_blocks:缓存池中空闲块的个数
    Qcache_free_memory:缓存中空闲内存量
    Qcache_hits:缓存命中次数
    Qcache_inserts:缓存写入次数
    Qcache_lowmen_prunes:因内存不足删除缓存次数
    Qcache_not_cached:查询未被缓存次数,例如查询结果超出缓存块大小,查询中包含可变函数等
    Qcache_queries_in_cache:当前缓存中缓存的SQL数量
    Qcache_total_blocks:缓存总block数

8. 减少缓存碎片策略:

选择合适的block大小
使用 FLUSH QUERY CACHE 命令整理碎片,这个命令在整理缓存期间,会导致其他连接无法使用查询缓存

清空缓存的命令

RESET QUERY CACHE; // 从查询缓存中移出所有查询。
FLUSH TABLES; //关闭所有打开的表,同时该操作将会清空查询缓存中的内容。
在这里插入图片描述

9. InnoDB查询缓存:

InnoDB存储引擎会对每个表设置一个事务计数器,里面存储当前最大的事务ID
当一个事务提交时,InnoDB会使用MVCC中系统最大的事务ID更新当前表的计数器
只有比这个最大ID大的事务能使用查询缓存,其他比这个ID小的事务则不能使用查询缓存
在InnoDB中,所有加锁操作的事务都不使用任何查询缓存
查询必须是完全相同的(逐字节相同)才能够被认为是相同的。
查询字符串由于其它原因使用不同的数据库、不同的协议版本或者不同的默认字符集都会被认为是不同的查询而分别进行缓存。

10. 参考:

mysql 缓存机制
MySQL查询缓存总结


http://chatgpt.dhexx.cn/article/IYAKT3Kp.shtml

相关文章

为什么数据库缓存如此重要?

您在数据库中拥有的信息越多,它随着时间的推移就会越慢。即使是为支持许多并发请求而精心设计的数据库管理系统也将最终达到极限。 数据库缓存是处理这些性能问题的最常见策略之一。缓存涉及将数据库查询的结果保存在更快,更容易访问的位置。正确完成后…

缓存 (模拟两种:数据库提供数据到缓存、外界提供数据到缓存)

一、缓存的作用 因此就有了缓存的作用: 代码模拟上面缓存的作用如下所示: 就拿以前我们做的通过id查询单条数据功能: 当开启服务器后,客户端访问该通过id查询单条数据功能时(假设连续访问两次)&#xff1a…

mysql的查询缓存

提高单台节点的性能无外乎就那么几种方式,缓存是首当其冲的,因为内存的性能比磁盘高的太多。缓存也是一种典型的空间换时间的策略 缓存的实现也有太多的方式,从静态页面缓存到服务端动态缓存,再到数据库级别缓存等等。随着大数据的…

缓存(本地缓存、分布式缓存)与数据库之间的数据一致性问题?

在现在的系统架构中,缓存的地位可以说是非常高的。因为在互联网的时代,请求的并发量可能会非常高,但是关系型数据库对于高并发的处理能力并不是非常强,而缓存由于是在内存中处理,并不需要磁盘的IO,所以非常…

mysql数据库缓存

一、开启缓存 mysql 开启查询缓存可以有两种方法来开启一种是使用set命令来进行开启,另一种是直接修改my.ini文件来直接设置都是非常的简单的哦。 开启缓存,设置缓存大小,具体实施如下: 1、修改配置文件my.ini windows下是my.i…

mysql 缓存机制

mysql缓存机制就是缓存sql 文本及缓存结果,用KV形式保存再服务器内存中,如果运行相同的sql,服务器直接从缓存中去获取结果,不需要在再去解析、优化、执行sql。 如果这个表修改了,那么使用这个表中的所有缓存将不再有效&#xff0c…

数据库缓存层

一 常见的缓存形式 : 1.文件缓存 (为了避免I/O开销,尽量使用内存缓存) 2.内存缓存 二 为什么要使用缓存 缓存数据是为了让客户端很少甚至不访问数据库服务器进行的数据查询,高并发下,能最大程度降低对数据库服务器的访问压力 一般的数据请求: 用户请求->数据查询->…

SQL查询缓存

适合读者 本教程适合于那些对缓存SQL查询以减少数据库连接与执行的负载、提高脚本性能感兴趣的PHP程序员。 概述 许多站点使用数据库作为站点数据存储的容器。数据库包含了产器信息、目录结构、文章或者留言本,有些数据很可能是完全静态的,这些将会从一个…

数据库之查询缓存

查询缓存配置 查看当前的MySQL数据库是否支持查询缓存SHOW VARIABLES LIKE have_query_cache; 查看当前MySQL是否开启了查询缓存SHOW VARIABLES LIKE query_cache_type; 查看查询缓存的占用大小SHOW VARIABLES LIKE query_cache_size; 查看查询缓存的状态信息show status li…

数据库缓存

一、什么是数据库缓存 我们知道常见的数据库,比如oracle、mysql等,数据都是存放在磁盘中。虽然在数据库层也做了对应的缓存,但这种数据库层次的缓存一般针对的是查询内容,而且粒度也太小,一般只有表中数据没有变更的时…

【技术干货】缓存随谈系列之一:数据库缓存

本文作者: 乔锐杰 现担任上海驻云信息科技有限公司运维总监/架构师。曾任职过黑客讲师、java软件工程师/网站架构师、高级运维、阿里云架构师等职位。维护过上千台服务器,主导过众安保险、新华社等千万级上云架构。在云端运维、分布式集群架构等方面有着丰富的经验。 以…

内连接、外连接、全连接图示语法

外连接 外连接分为外左连接(left outer join)和外右连接(right outer join) left outer join 与 left join 等价, 一般写成left join right outer join 与 right join等价, 一般写成right join左连接:左侧交集部分 语法:…

MySQL 内连接、外连接、左连接、右连接、全连接

建表语句: CREATE TABLE a_table (a_id int(11) DEFAULT NULL,a_name varchar(10) DEFAULT NULL,a_part varchar(10) DEFAULT NULL ) ENGINEInnoDB DEFAULT CHARSETutf8CREATE TABLE b_table (b_id int(11) DEFAULT NULL,b_name varchar(10) DEFAULT NULL,b_part v…

SQL中的各种连接的区别总结(内连接,左连接,左外连接,右连接,右外连接,全连接,全外连接)

在数据库中建立两张表方便大家理解,teacher和student表(student表中的teacherid字段是对应teacher表中的ID,举个例子张三的老师就是李四,没有teacherid就是这个人暂时没有老师) INNER JOIN: 返回两个表的匹配得上的数据,不匹配不…

MYSQL语法:左连接、右连接、内连接、全外连接

文章目录 概念上手使用left join(左连接)rint join(右连接)inner join(内连接,等同join)full join(全连接,等同full outer join) 概念 left join(左连接):返回包括左表中…

MySQL 的等值连接、交叉连接、左外连接 、右外连接、全外连接实例

1. 测试数据 测试数据如下所示,数据库脚本(含数据)在文章最后的附录中给出。 测试工具:MySQL8.0 , Navicat Premium。 首先是一个班级表:class,class表中的数据如下所示。 学生表: student&a…

数据库学习之MySQL (十六)—— SQL99 外连接 左外连接 右外连接 全外连接 交叉连接

文章目录 外连接 之 左外连接 与 右外连接为啥要用外连接全外连接总结 内连接 外连接交叉连接 外连接 之 左外连接 与 右外连接 我们先来看个之前的 女神男朋友的案例 传送:数据库学习之MySQL (十三)——多表查询 SQL92 SQL99 连接种类划分 我们先考虑…

ORACLE的左右连接,全外连接

先上概念 oracle连接分为: 左外连接:左表不加限制,保留左表的数据,匹配右表,右表没有匹配到的行中的列显示为null。 右外连接:右表不加限制,保留右表的数据。匹配左表,左表没有匹配…

SQL的内连接、左连接、右连接、 交叉连接、全外连接

sql表连接分成 外连接 、 内连接 和 交叉连接。. 外连接包括三种,分别是左外连接、右外连接、全外连接。. 对应的sql关键字:LEFT/RIGHT/FULL OUTER JOIN,通常我们都省略OUTER关键字,写成LEFT/RIGHT/FULL JOIN。. 在左、右外连接中都会以一种表为基表,基表的所有行、…

Mysql中实现全外连接

MySql中多表查询只提供了内连接,左外连接与右外连接: table_reference {[INNER] JOIN | {LEFT|RIGHT} [OUTER] JOIN} table_reference ON conditional_expr 1】INNER JOIN ON内连接(只写join时默认为内连接) SELECT * FROM emp e…