13MySQL-查询缓存Query Cache
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了13MySQL-查询缓存Query Cache相关的知识,希望对你有一定的参考价值。
查询缓存原理
Query Cache是mysql中的一个缓存机制,可以缓存SELECT语句的查询结果,提高查询性能。当再次执行相同的查询语句时,MySQL会尝试从缓存中获取结果,而不必重新执行查询语句。
Query Cache的工作流程如下:
1、当一个SELECT语句执行时,MySQL会先检查查询缓存,是否有该查询的结果。
2、如果缓存中有该查询的结果,则直接返回结果给客户端。
3、如果缓存中没有该查询的结果,则执行查询语句,将结果存储到缓存中,并返回结果给客户端。
可以使用以下语句查看Query Cache的状态:
SHOW VARIABLES LIKE query_cache_%;
Query Cache的状态可以通过修改以下系统变量进行配置:
query_cache_type:决定Query Cache的开启和关闭,默认为ON。
query_cache_size:决定Query Cache的大小,以字节为单位,默认为0,表示不限制大小。
query_cache_limit:决定Query Cache中单个结果集的大小限制,以字节为单位,默认为1MB。
注:1、Query Cache只适用于对静态数据的查询,并且可能会因为查询结果集的不断更新而失效。因此,在高并发、动态更新频繁的应用场景中,建议关闭Query Cache;
2、缓存SELECT操作或预处理查询的结果集和SQL语句,当有新的SELECT语句或预处理查询语句请求,先去查询缓存,判断是否存在可用的记录集,判断标准:与缓存的SQL语句,是否完全一样,区分大小写。
哪些语句不能使用缓存
使用了用户自定义函数
使用了非确定性函数,例如 NOW() 和 UUID()
使用了系统变量,例如 @@GLOBAL.server_uuid 和 @@SESSION.sql_mode
语句中包含了用户变量或者全局变量
查询中使用了临时表
查询中使用了不支持缓存的存储引擎,例如 BLOB 和 TEXT 类型的列
查询中使用了 LOCK TABLES 和 UNLOCK TABLES 语句
查询中使用了多表更新和删除操作
查询语句中加了SQL_NO_CACHE参数
某用户只有列级别权限的查询语句
事务隔离级别为Serializable时,所有查询语句都不能缓存
查询缓存相关的服务器变量
query_cache_type:指定查询缓存使用的类型,可以是 ON、OFF 或 DEMAND。ON 表示缓存所有 SELECT 语句(默认值),OFF 表示不使用缓存,DEMAND 表示只有当语句中包含 SQL_CACHE 关键字时才使用缓存。
query_cache_size:指定查询缓存可用的内存大小,以字节为单位。
query_cache_limit:指定单个查询结果可以缓存的最大值,以字节为单位。
query_cache_min_res_unit:指定每个查询结果块的最小大小,以字节为单位。
query_cache_strip_comments:指定是否从查询语句中删除注释,以便更好地利用查询缓存。
query_cache_wlock_invalidate:指定在查询缓存中缓存表时是否自动失效其他客户端的写锁。
query_cache_mutexes:指定查询缓存使用的互斥锁数目。
这些变量可以通过 SET 命令修改,也可以通过在 my.cnf 文件中设置来永久更改。
SELECT语句的缓存控制
SELECT语句的缓存控制可以通过在SQL语句中使用SQL_CACHE和SQL_NO_CACHE来实现。
使用SQL_CACHE来显式指定SELECT语句使用缓存,例如:
SELECT SQL_CACHE * FROM users WHERE id = 1;
使用SQL_NO_CACHE来显式指定SELECT语句不使用缓存,例如:
SELECT SQL_NO_CACHE * FROM users WHERE id = 1;
需要注意的是,如果查询语句中包含非确定性的函数(例如NOW()、UUID()等)或用户变量,即使使用了SQL_CACHE,也不会被缓存。因此,在使用查询缓存时,应该尽量避免使用这些函数和变量。
此外,查询缓存的开销也比较大,因此在高并发的情况下,应该谨慎使用查询缓存
查询缓存状态变量
MySQL 8.0 版本已经弃用查询缓存,因此在该版本中无法查询和配置与查询缓存相关的状态变量。但是,在 MySQL 5.7 及更早版本中,可以使用以下命令查询与查询缓存相关的状态变量:
Qcache_free_blocks:查询缓存中空闲块的数量。
Qcache_free_memory:查询缓存中可用于存储查询结果的空闲内存量,以字节为单位。
Qcache_hits:从查询缓存中获取结果的次数。
Qcache_inserts:将查询结果存储到查询缓存中的次数,未命中次数。
Qcache_lowmem_prunes:由于内存压力而从查询缓存中删除结果的次数。
Qcache_not_cached:由于查询语句不符合查询缓存规则而未被缓存的查询数量。
Qcache_queries_in_cache:当前存储在查询缓存中的查询数量。
Qcache_total_blocks:查询缓存中块的总数量。
可以使用以下命令查询这些状态变量的值:
SHOW GLOBAL STATUS LIKE Qcache%;
需要注意的是,在使用查询缓存时,需要在 MySQL 配置中启用它,可以设置query_cache_type变量的值为 DEMAND、ON 或 OFF,以决定查询缓存是否启用,如下所示:
SET GLOBAL query_cache_type = ON;
也可以在 MySQL 配置文件 my.cnf 中设置 query_cache_type 来进行持久化配置。
命中率和内存使用率估算
查询缓存中内存块的最小分配单位query_cache_min_res_unit :
(query_cache_size - Qcache_free_memory) / Qcache_queries_in_cache
查询缓存命中率
命中率 = (Qcache_hits / (Qcache_hits + Qcache_inserts)) * 100%。
查询缓存内存使用率
内存使用率指的是查询缓存使用的内存占所有可用内存的比例,其计算公式为:内存使用率 = (query_cache_size – qcache_free_memory) / query_cache_size * 100%
查询缓存优化
以下是 MySQL 查询缓存优化的流程:
1、检查查询缓存是否开启
2、如果开启了查询缓存,检查当前查询是否在缓存中
3、如果当前查询在缓存中,直接从缓存中返回结果
4、如果当前查询不在缓存中,执行查询并将结果缓存起来
5、检查缓存是否达到了缓存大小限制,如果达到了限制,清空缓存
6、定期检查缓存中的数据是否过期,如果过期,从缓存中删除
7、不适合缓存的查询不应该缓存,例如包含随机数或时间戳的查询
8、避免在写操作后立即进行读操作,这会使缓存失效
9、避免在频繁更新的表上使用查询缓存,这会导致缓存频繁失效
10、对于需要进行排序或分组的查询,不适合使用查询缓存
以上是 MySQL 查询缓存优化的流程图,注意需要根据实际情况调整和优化。
MySQL查询缓存虽然可以提高查询速度,但在高并发环境下使用也会带来一些问题,比如查询缓存锁等待、缓存清除导致CPU负载高等。以下是一些查询缓存优化的建议:
1、设置合适的缓存大小
查询缓存的大小决定了它可以缓存多少查询结果,过大会占用过多的内存,过小则无法缓存足够多的查询结果。可以使用query_cache_size变量来调整缓存大小,建议将其设置为总内存的10%左右。
2、限制缓存可用范围
查询缓存是基于查询语句的,如果查询中含有变量或者当前时间等动态因素,则无法缓存。可以使用query_cache_type变量将其设置为DEMAND模式,只有显式启用缓存的查询才会被缓存。
3、避免使用不必要的大查询
查询缓存只有在查询结果完全匹配时才能被使用,因此如果查询结果集很大,则缓存的效率会很低。可以尽量避免返回过大的结果集,或者使用分页查询等方式降低结果集大小。
4、使用缓存提高重复查询性能
如果某个查询会被重复执行,可以使用SQL_CACHE关键字强制使用查询缓存,提高查询性能。但是需要注意,如果查询结果很少被重复使用,则这种方式会占用不必要的缓存空间。
5、调整锁等待超时时间
当查询缓存锁被占用时,查询请求会等待锁释放。可以使用query_cache_lock_wait_timeout变量来调整等待超时时间,减少等待时间对系统性能的影响。但是需要注意,等待时间过短会导致缓存的重复利用率降低。
6、监控缓存状态
可以通过SHOW STATUS命令来查看查询缓存的状态变量,比如缓存命中率、缓存大小和已用缓存量等。通过监控这些状态变量,可以及时调整缓存大小和使用策略,保证系统性能的稳定和可靠。
Page Cache buffer Cache
https://www.thomas-krenn.com/en/wiki/Linux_Page_Cache_Basics
References
- Jump up ↑ The Buffer Cache (Section 15.3) page 348, Linux-Kernel Manual: Guidelines for the Design and Implementation of Kernel 2.6, Robert Love, Addison-Wesley, 2005
- Jump up ↑ Linux 2.6. – 32 Per-backing-device based writeback (kernelnewbies.org)
- Jump up ↑ Clearing The Linux Buffer Cache (blog.straylightrun.net, 03.12.2009)
- Jump up ↑ Improving Linux performance by preserving Buffer Cache State (insights.oetiker.ch)
Additional Information
- Page Cache, the Affair Between Memory and Files (Blog)
- Linux buffer cache state (Blog)
- The Linux Page Cache and pdflush: Theory of Operation and Tuning for Write-Heavy Loads (Last update 8/08/2007)
- drop_caches (linuxinsight.com)
- Examining Linux 2.6 Page-Cache Performance (linuxinsight.com)
- Page cache (en.wikipedia.org)
以上是关于13MySQL-查询缓存Query Cache的主要内容,如果未能解决你的问题,请参考以下文章