不做大哥好多年 不做大哥好多年
首页
  • MySQL
  • Redis
  • Elasticsearch
  • Kafka
  • Etcd
  • MongoDB
  • TiDB
  • RabbitMQ
  • 01.Python
  • 02.GO
  • 03.Java
  • 04.业务问题
  • 05.关键技术
  • 06.项目常识
  • 10.计算机基础
  • Docker
  • K8S
  • 容器原理
  • Istio
  • 01.GO基础
  • 02.面向对象
  • 03.并发编程
  • 04.常用库
  • 05.数据库操作
  • 06.Beego框架
  • 07.Beego商城
  • 08.GIN框架
  • 09.GIN论坛
  • 10.微服务
  • 01.Python基础
  • 02.Python模块
  • 03.Django
  • 04.Flask
  • 05.SYL
  • 06.Celery
  • 10.微服务
  • 01.Java基础
  • 02.面向对象
  • 03.Java进阶
  • 04.Web基础
  • 05.Spring框架
  • 100.微服务
  • 数据结构
  • 算法基础
  • 算法题分类
  • 前置知识
  • PyTorch
  • Langchain
  • Linux基础
  • Linux高级
  • Nginx
  • KeepAlive
  • ansible
  • zabbix
  • Shell
  • Linux内核

逍遥子

不做大哥好多年
首页
  • MySQL
  • Redis
  • Elasticsearch
  • Kafka
  • Etcd
  • MongoDB
  • TiDB
  • RabbitMQ
  • 01.Python
  • 02.GO
  • 03.Java
  • 04.业务问题
  • 05.关键技术
  • 06.项目常识
  • 10.计算机基础
  • Docker
  • K8S
  • 容器原理
  • Istio
  • 01.GO基础
  • 02.面向对象
  • 03.并发编程
  • 04.常用库
  • 05.数据库操作
  • 06.Beego框架
  • 07.Beego商城
  • 08.GIN框架
  • 09.GIN论坛
  • 10.微服务
  • 01.Python基础
  • 02.Python模块
  • 03.Django
  • 04.Flask
  • 05.SYL
  • 06.Celery
  • 10.微服务
  • 01.Java基础
  • 02.面向对象
  • 03.Java进阶
  • 04.Web基础
  • 05.Spring框架
  • 100.微服务
  • 数据结构
  • 算法基础
  • 算法题分类
  • 前置知识
  • PyTorch
  • Langchain
  • Linux基础
  • Linux高级
  • Nginx
  • KeepAlive
  • ansible
  • zabbix
  • Shell
  • Linux内核
  • MySQL

    • 01.安装MySQL
    • 02.MySQL事务
    • 03.MySQL锁
    • 04.MySQL索引 ✅
    • 05.MySQL慢查询
    • 06.MySQL优化
    • 07.binlog redolog undolog ✅
    • 08.MVCC原理 ✅
    • 09.SQL执行过程 ✅
    • 10.MySQL主从同步
    • 11.MySQL主从配置
    • 12.MySQL和Redis一致性
    • 13.MySQL查询缓存
      • 01.MySQL查询缓存
        • 1、概述
        • 2、缓存规则
        • 3、缓存机制中的内存管理
        • 4、查询缓存的优缺点
        • 5、总结
    • 90.其他
    • 95.MySQL管理
    • 96.MySQL基本查询
    • 97.创建表结构
    • 98.SQL语句面试50题
    • 99.FAQ
  • Redis

  • Elasticsearch

  • Kafka

  • Etcd

  • MongoDB

  • TiDB

  • RabbitMQ

  • 数据库
  • MySQL
xiaonaiqiang
2024-03-18
目录

13.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

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

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

    • 重复的查询很少

    • 查询的结果集很大

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

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

参考 (opens new window)

上次更新: 2024/10/15 16:27:13
12.MySQL和Redis一致性
90.其他

← 12.MySQL和Redis一致性 90.其他→

最近更新
01
05.快递Agent智能体
06-04
02
200.AI Agent核心概念
06-04
03
105.Agent智能体梳理
06-04
更多文章>
Theme by Vdoing | Copyright © 2019-2025 逍遥子 技术博客 京ICP备2021005373号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式