MySQL查询缓存 mysql
用于保存MySQL查询语句返回的完整结果,被命中时,sql
MySQL会当即返回结果,省去解析、优化和执行等阶段缓存
并发查询量很是大、cup核心数很是多时缓存并不必定有效bash
(多个线程会争用存储缓存的这段内存空间)服务器
如何检查缓存???并发
MySQL保存结果与缓存中:ide
把select语句自己作hash计算,计算的结果做为key,查询结果做为value函数
什么样的语句不会被缓存?性能
查询语句中有一些不肯定数据时,不会缓存;例如now(),current_time();优化
通常来讲,若是查询中包含用户自定义函数、存储函数、用户变量、临时表、mysql库中系统表、或者任何包含权限的表,通常都不会缓存
缓存会带来额外开销
一、每一个查询都会先检查是否命中
二、查询结果要先缓存(写缓存)
查看跟缓存相关的变量
mysql> show global variables like 'query_cache%'; +------------------------------+----------+ | Variable_name | Value | +------------------------------+----------+ | query_cache_limit | 1048576 | | query_cache_min_res_unit | 4096 | | query_cache_size | 16777216 | | query_cache_type | ON | | query_cache_wlock_invalidate | OFF | +------------------------------+----------+ query_cache_type:查询缓存类型:是否开启缓存功能,开启方式有三种{ON|OFF|DEMAND} DEMAND:意味着select语句明确使用sql_cache选项才会缓存 (SQL_NO_CACHE则不会缓存) query_cache_size:总空间;单位为字节,大小必须为1024的整数倍.mysql启动时,会一次分配并当即初始化这里指定大小的内存空间; 这意味着,若是修改此大小,会清空缓存并从新初始化的. query_cache_min_res_unit:存储缓存的最小内存块;(query_cache_size - Qcache_free_memory) / Qcache_queries_in_cache 可以得到一个理想的值 设置过大,容易浪费;设置太小,容易产生大量碎片 query_cache_limit:单个缓存对象的最大值,超出时则不予缓存;手动使用SQL_NO_CACHE能够人为的避免尝试缓存返回超出此参数限定值得语句 query_cache_wlock_invalidate:若是某个表被其余用户链接锁住了,是否仍然从缓存中返回结果,OFF表示返回
如何判断命中率:
分为次数和字节命中率(命中之后,所省去的数据传输量或解析自己所开销的大小)
mysql> show global status like 'Qcache%'; +-------------------------------------------------+----------+ | Variable_name | Value | +-------------------------------------------------+----------+ | Qcache_free_blocks(空闲块数) | 1 | | Qcache_free_memory(空闲空间) | 16759688 | | Qcache_hits(命中次数) | 0 | | Qcache_inserts (插入次数) | 2 | | Qcache_lowmem_prunes(内存过小,修剪内存的次数) | 0 | | Qcache_not_cached(没被缓存的个数) | 8 | | Qcache_queries_in_cache(缓存中缓存的查询个数) | 0 | | Qcache_total_blocks(总块数) | 1 | +-------------------------+----------------------------------+
碎片整理 mysql > flush query_cache
清空缓存 mysql > reset query_cache
计算命中率:
mysql > show global status where Vaiable_name='Qcache_hits' OR Variable_name='Com_Select';
Qcache_hits/(Qcache_hits + Com_Select)
mysql> show global status where Variable_name='Qcache_hits' OR Variable_name='Com_Select'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | Com_select | 25 | // 总查询此时,命中则不会累计 | Qcache_hits | 3 | +---------------+-------+ 命中率=3/(3+25)
缓存优化思路
1.批量写入,而非屡次单个写入
2.缓存空间不宜过大,由于大量缓存同事失效时会致使服务器假死
3.必要时,使用sql_CACHE和sql_no_cache手动控制缓存。
4.对写密集型的应用场景来讲,禁用缓存反而提升性能。