关于MariaDB查询缓存那些事

2023年 7月 15日 31.8k 0

MySQL查询缓存

1,当语句提交给查询语句之前是做过解析的,如果将查询计划缓存2,将查询结果缓存,当同样的用户只需同样的语句查询时则返回缓存查询结果MySQL查询缓存,用于保存查询语句返回的完整结果,被命中,MySQL会立即返回结果,省去解析,优化和执行等阶段性的操作!

当多个用户连接到MYSQL,多个用户使用单独的CPU进行单独的语句查询,当命中缓存,缓存则成为多个资源的争用所在,在某些时刻,这段内存空间中只可以允许一个cpu访问

当用户请求到---》检查缓存是否命中----》命中则缓存查找,未命中则解析,优化,执行,取得结果后,是否进行缓存,是则缓存,而后返回给用户缓存查询.png

如何检查缓存?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_commentsMariaDB独有的

命中率判断:命中大小和命中次数,查询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_CACHEFLUSH 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,对于密集型的应用场景来说,禁用操作反而能提供缓存(如果写入较多,则无需开启)

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论