是否需要开启查询缓存
从 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%”;
- 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%”;
- 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 () 等