MySQL查询缓存
1,当语句提交给查询语句之前是做过解析的,如果将查询计划缓存2,将查询结果缓存,当同样的用户只需同样的语句查询时则返回缓存查询结果MySQL查询缓存,用于保存查询语句返回的完整结果,被命中,MySQL会立即返回结果,省去解析,优化和执行等阶段性的操作!
当多个用户连接到MYSQL,多个用户使用单独的CPU进行单独的语句查询,当命中缓存,缓存则成为多个资源的争用所在,在某些时刻,这段内存空间中只可以允许一个cpu访问
当用户请求到---》检查缓存是否命中----》命中则缓存查找,未命中则解析,优化,执行,取得结果后,是否进行缓存,是则缓存,而后返回给用户
如何检查缓存?MySQL保存数据于缓存中:是通过吧SELECT语句本身做HASH计算,计算结果作为KEY,查询结果作为value
缓存命中:字节命中次数命中
不会被缓存的内容:查询语句中不确定的数据时,不会缓存,如:NOW(),CURRENT_TIME(),一般来讲,如果查询中包含用户自定义函数,存储函数,用户变量,临时表,mysql库系统表,或者任何包含全险的表,一般都不会缓存
缓存会带来额外的开销:1,每一个查询都需要检查是否命中2,查询结果要先缓存
查询缓存是在内存中运行,当缓存申请内存的申请和分配,释放内存,当内存申请,分配,释放很频繁,缓存大小固定的时候会形成一定的碎片,内存分配回收策略至关重要
语句大小写许一种类型,全大写或全小写
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'query_cache%';
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 10
Current database: *** NONE ***
+------------------------------+----------+
| Variable_name | Value |
+------------------------------+----------+
| query_cache_limit | 1048576 |
| query_cache_min_res_unit | 4096 |
| query_cache_size | 33554432 |
| query_cache_strip_comments | OFF |
| query_cache_type | ON |
| query_cache_wlock_invalidate | OFF |
+------------------------------+----------+
6 rows in set (0.04 sec)
MariaDB [(none)]>
query_cache_type
查询缓存类型,是否开启缓存功能,但是开启的方式有三种((ON开启),(OFF关闭),(DEMAND,意味着SELECT语句明确使用SQL_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表示返回
query_cache_strip_comments
MariaDB独有的
命中率判断:命中大小和命中次数,查询100次只命中20次,但这20次每次查询结果有1M的返回,其他80次每次只有几个字节的返回,那么20次的命中率仍然很高。
MariaDB [(none)]> SHOW GLOBAL STATUS LIKE 'Qcache%';
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_free_blocks | 1 |
| Qcache_free_memory | 33536856 |
| Qcache_hits | 4 |
| Qcache_inserts | 2 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 14 |
| Qcache_queries_in_cache | 2 |
| Qcache_total_blocks | 6 |
+-------------------------+----------+
8 rows in set (0.00 sec)
MariaDB [(none)]>
状态变量是mysql对于当前系统执行查询操作的统计结果,服务器变量是可以调整的
Qcache_hits :
缓存命中次数Qcache_inserts :
向缓存空间中写入缓存数据的次数Qcache_free_memory:
尚且空闲的空间Qcache_free_blocks
:空闲快Qcache_total_blocks
:总快数 (事先分配好的)(缓存空间是被初始化,分配之后才用来缓存数据,空闲空间是未使用的空间,总空间减去空闲则是已用,但也未必)Qcache_queries_in_cache
:在缓存中缓存的查询的个数(如:缓存有50个,但是插入了60次)Qcache_not_cached
:没有缓存的Qcache_lowmem_prunes
:内存太少,而修剪释放的内存次数
如果空闲空间扔由很多,但是总是被修剪,有大量碎片导致无法缓存的,则需要碎片整理,如:FLUSH QUERY_CACHE
FLUSH QUERY_CACHE
可将随便整理出来,将碎片链接清空缓存:RESET QUERY_CACHE
,清空缓存则需要重新预热
次数命中率的估算方式:
MariaDB [(none)]> SHOW GLOBAL STATUS WHERE Variable_name='Qcache_hits' OR Variable_name='Com_select';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_select | 17 |
| Qcache_hits | 0 |
+---------------+-------+
2 rows in set (0.00 sec)
MariaDB [(none)]>
Com_select 17 + Qcache_hits 0 = 命中率
Qcache_hits/(Com_select +Qcache_hits )
而字节命中率很难进行估算!
命中和写入的比率:即Qcache_hits/Qcache_instrts
的值,此值如果能大于3比1,能大于3则表示缓存也是有效的,能达到10比1,通常为理想值结合以上的值来判断缓存是否有效,还是存在缓存抖动!
缓存使用优化方式:1,批量写入,而非多次单个写入2,缓存空间不宜设置太大,因为大量缓存如果同时失效则会导致服务器假死3,必要时,使用SQL_CACHE和SQL_NO_CACHE手动控制缓存4,对于密集型的应用场景来说,禁用操作反而能提供缓存(如果写入较多,则无需开启)