MySQL-21丨是否需要开启查询缓存

Posted by jiefang on November 1, 2019

是否需要开启查询缓存

从 MySQL 4.1 开始,增加了查询缓存(Query Cache,简称 QC)的功能,它会存储 select 语句的文本以及发送到客户端的结果。如果下一次收到一个相同的查询,就会从查询缓存中获得查询结果。

从MySQL 5.7.20开始,查询缓存已被弃用,并在MySQL 8.0中被删除。

认识 QC

QC 需要缓存最新数据结果,因此表数据发生任何变化(insert、update、delete 等操作时),都会导致 QC 被刷新。

查询缓存相关的参数主要有:

show variables like “%query_cache%”;

image

  • have_query_cache:服务器在安装时是否已经配置了高速缓存
  • query_cache_limit:单条查询能够使用的缓存区大小
  • query_cache_min_res_unit:查询缓存分配内存块的最小单位
  • query_cache_size:缓存区的大小
  • query_cache_type:缓存类型,有三个值可选:
    • 0 或者 off:关闭缓存
    • 1 或者 on:打开缓存
    • 2 或者 demand:只缓存带有 sql_cache 的 select 语句。
  • query_cache_wlock_invalidate:如果某个数据表被其它的连接锁住,是否仍然从查询缓存中返回结果

查询缓存的使用情况:

show global status like “qcache%”;

image

  • Qcache_free_blocks:查询缓存中的空闲内存块的数目
  • Qcache_free_memory:查询缓存的空闲内存总数
  • Qcache_hits:缓存命中次数
  • Qcache_inserts:被加入到缓存中的查询数目
  • Qcache_lowmem_prunes:因为缺少内存而从缓存中删除的查询数目
  • Qcache_not_cached:没有被缓存的查询数目
  • Qcache_queries_in_cache:在缓存中已注册的查询数目
  • Qcache_total_blocks:查询缓存中的块的总数目

QC的优劣

QC 优势:

  • 提高查询速度:使用查询缓存在单行数据的表中搜索要比不使用查询缓存快 238%

劣势:

  • 比如执行的 SQL 都很简单(比如从只有一行的表中查询数据),但每次查询都不一样的话,打开 QC 后,额外的开销为 13% 左右;
  • 如果表数据发生了修改,使用该表的所有缓存查询都将实效,并且从缓存中删除;
  • QC 要求前后两次请求的SQL完全一样,不同数据库、不同协议版本或不同默认字符集的查询,都会被认为是不同的查询,甚至包括大小写.
  • 每次更新 QC 的内存块都需要进行锁定
  • 可能会导致 SQL 查询时间不稳定

是否需要开启

  • 如果线上环境中 99% 以上都是只读,很少更新,可以考虑全局开启 QC,也就是设置 query_cache_type 为 1。
  • 希望缓存的是几张更新频率很低的表,其它表不考虑使用查询缓存,就可以考虑将 query_cache_type 设置成 2 或者 DEMAND。
  • 其它情况就不建议开启 QC。

开启 QC 的注意事项

如果要开启 QC,建议不要设置过大,通常几十兆就好。如果设置过大,会增加维护缓存所需要的开销。

即使开启 QC 也不能使用 QC 的场景:

  • 分区表不支持,如果涉及分区表的查询,将自动禁用查询缓存
  • 子查询或者外层查询
  • 存储过程、触发器中使用的 SQL
  • 读取系统库时
  • 类似下面 SQL 时:
    • select … lock in share mode
    • select … for update
  • 用到临时表
  • 产生了 warning 的查询
  • 显示增加了 SQL_NO_CACHE 关键字的
  • 如果没有全部库、表的 select 权限,则也不会使用 QC
  • 使用了一些函数:比如 now (),user (),password () 等