mysql 缓存机制

1. MySQL缓存简介

1. MySQL缓存机制说明

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

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. 工做流程

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

4. 缓存失败

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

5. 缓存的内存管理

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

MySQL缓存管理

6. 缓存的使用时机

1. 经过缓存命中率判断

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

2. 经过缓存写入率判断

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

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;

3. query_cache_size

  • 缓存使用的总内存空间大小,单位是字节,这个值必须是1024的整数倍;不然MySQL实际分配可能跟这个数值不一样(感受这个应该跟文件系统的blcok大小有关)
  • 默认状况下query_cache_size为0,表示为查询缓存预留的内存为0,则没法使用查询缓存
  • 设置query_cache_size的值
    • SET GLOBAL query_cache_size = 134217728; -- 注意值若是设得过小不会生效

4. query_cache_min_res_unit

分配内存块时的最小单位大小数据结构

5. query_cache_limit

MySQL可以缓存的最大结果,若是超出,则增长 Qcache_not_cached的值,并删除查询结果函数

6. query_cache_wlock_invalidate

若是某个数据表被锁住,是否仍然从缓存中返回数据,默认是OFF,表示仍然能够返回性能

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

8. 减小缓存碎片策略

  1. 选择合适的block大小
  2. 使用 FLUSH QUERY CACHE 命令整理碎片,这个命令在整理缓存期间,会致使其余链接没法使用查询缓存

清空缓存的命令

RESET QUERY CACHE; // 从查询缓存中移出全部查询。
FLUSH TABLES; //关闭全部打开的表,同时该操做将会清空查询缓存中的内容。

MySQL缓存配置

9. InnoDB查询缓存

    1. InnoDB存储引擎会对每一个表设置一个事务计数器,里面存储当前最大的事务ID
    2. 当一个事务提交时,InnoDB会使用MVCC中系统最大的事务ID更新当前表的计数器
    3. 只有比这个最大ID大的事务能使用查询缓存,其余比这个ID小的事务则不能使用查询缓存
    4. 在InnoDB中,全部加锁操做的事务都不使用任何查询缓存
    5. 查询必须是彻底相同的(逐字节相同)才可以被认为是相同的。
    6. 查询字符串因为其它缘由使用不一样的数据库、不一样的协议版本或者不一样的默认字符集都会被认为是不一样的查询而分别进行缓存。
相关文章
相关标签/搜索