文章目录

  • 1. MysQL
  • 1.1 何时缓存
  • 1.2 何时缓存失效
  • 2.MySQL缓存简介
  • 2.1 Mysql缓存机制说明
  • 2.2 Mysql缓存失效
  • 2.3 命中条件
  • 2.4 工作流程
  • 2.5 缓存失败
  • 2.6 缓存的内部管理
  • 2.7 缓存的使用时机
  • 2.8 缓存参数配置


1. MysQL

1.1 何时缓存

  • 缓存的key:SOL(所以sq语句要完全相同才能使用上缓存)
    缓存的value:结果集
  • where条件中如包含了某些函数永远不会被缓存,比如current_date,now等
  • 太大的结果集不会被缓存

1.2 何时缓存失效

  • 表数据有任何修改,则有关于该表的数据全部失效

2.MySQL缓存简介

2.1 Mysql缓存机制说明

Mysql缓存机制即缓存Sql文本以及缓存结果,用kv形式保存在服务器内存中,如果运行相同的Sql,服务器直接从缓存中获取结果,不需要取解析,优化,执行Sql

2.2 Mysql缓存失效

  • 在表结构或者数据发生改变时,查询缓存中的数据不再有效,查询缓存的相关条目也被清空
  • Insert Update Delete Truncate alter drop table或者drop database将导致缓存失效

2.3 命中条件

  • 缓存的数据结构是hash表
  • 以Sql,数据集合和客户端协议等为key
  • 在判断命中前,Mysql不会解析SQL,而是使用SQL去查询缓存,sql的任何字段不同都会导致缓存不命中,如果查询有不确定的数据,如 like now() current_date() ,不会缓存

2.4 工作流程

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

2.5 缓存失败

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

2.6 缓存的内部管理

  • Mysql缓存机制会在内存中开辟一块内存(query_cache_size)区来维护缓存数据,其中有部分空间是用来维护为缓存数据的元数据的,列如 空间缓存,数据表和查询结果的映射,sql和查询结果的映射;
  • Mysql缓存机制将大内存块分为小内存块(query_cache_min_res_unit),每个小块中存储自身的类型,大小和查询结果数据,还有前后内存块的映射;
  • Mysql缓存机制会在Sql查询开始(还未得到结果)时就去申请一块内存空间,所以即使缓存数据没有达到这个大小也需要占用申请的内存块空间(like linux filesystem block),如果超出申请内存块大小,则需要申请一个内存块,当查询完成发现申请的内存有富余,则会将富余的内存空间释放掉,因而可能会造成内存碎片;

2.7 缓存的使用时机

  • 通过缓存命中率判断

缓存命中率=缓存命中次数(Qcache_hits)/查询次数(Com_select)

  • 通过缓存写入率判断

写入率=缓存写入次数(Qcache_inserts)/查询次数(Qcache_insert)

  • 通过命中-写入率判断

比率=命中次数(Qcache_hits)/写入次数(Qcache_inserts)
高性能Mysql中称之为较能反映性能提升的指数,一般来说达到3:1则算是查询缓存有效,而最好能够达到10:1

2.8 缓存参数配置

  • 查看缓存相关配置

SHOW VARIABLES LIKE ‘%query_cache%’;

  • 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
  • query_cache_size
  • 缓存使用的总内存大小,单位是字节,这个值必须是1024的整数倍,否则Mysql实际可分配可能跟这个数值不同
  • 默认情况下query_cache_size为0,表示查询缓存的预留的内存为0,则无法使用查询缓存
  • 设置query_cache_size的值
  • set global query_cache_size=134217728 注意值如果设置的太小不会生效
  • query_cache_min_res_unit
    分配内存块时的最小单位大小
  • query_cache_limit
    Mysql能够缓存的最大结果,如果超出,则增加Qache_not_cache的值,并删除查询结果
  • query_cache_wlock_invalidate
    如果某个数据表被锁住,是否仍然从缓存中返回数据,默认是OFF,表示仍然可以返回
  • GLOBAL STATUS 中关于缓存的参数解释
  • 1.Qcache_free_blocks:缓存池中空闲块的个数
  • 2.Qcache_free_memory:缓存中空闲内存量
  • 3.Qcache_hits:缓存命中次数
  • 4.Qcache_inserts:缓存写入次数
  • 5.Qcache_lowmen_prunes:因内存不足删除缓存次数
  • 6.Qcache_not_cached:查询未被缓存次数,例如查询结果超出缓存块大小,查询中包含可变函数等
  • 7.Qcache_queries_in_cache:当前矮存中缓存的SQL数量
  • 8.Qcache_total_blocks:缓存总block数
  • 减少缓存碎片策略
  • 选择合适的block大小
  • 使用Flush QUERY CACHE 命令整理碎片,这个命令在整理缓存期间,会导致其他连接无法使用查询缓存
  • 清空缓存的命令
    RESET QUERY CACHE 查询缓存中移除所有查询
    FLUSH TABLES 关闭所有打开的表,同时该操作将会清空查询缓存中的内容
  • InnoDB 查询缓存
  • InnoDB存储引擎会对每一个表设置一个事务计数器,里面存储当前最大的事务Id
  • 当一个事务提交时,Innodb会使用MVCC系统最大的事务ID更新当前表的计数器
  • 只有比这个最大ID大的事务能使用查询缓存,其他不能使用
  • 在InnoDB中,所有加锁操作的事务不使用任何查询缓存
  • 查询必须时完全相同的
  • 查询字符串由于其他原因使用不同的数据库,不同版本协议或者不同的默认字符都会认为是不同的查询而分别缓存