MySQL QueryCache原理经典讲解

数据库 MySQL
以下的文章主要描述的是MySQL QueryCache原理讲述,以下的文章主要是对MySQL QueryCache原理的详细解析,以下就是文章的具体内容描述。

我们大家都知道MySQL QueryCache(下面简称QC)它是根据实际应用的SQL语句来cache 的。一个相关的SQL查询,如果它是以select开头的话,其MySQL服务器就会尝试对其使用 QC。每个Cache都是以SQL文本作为key来存的。

在应用QC之前,SQL文本不会被作任何处理。

也就是说,两个SQL语句,只要相差哪怕是一个字 符(例如大小写不一样;多一个空格等),那么这两个SQL将使用不同的一个CACHE。不过SQL文本有可能会被客户端做一些处理。例如在官方的命令行客 户端里,在发送SQL给服务器之前,会做如下处理:

 

1、过滤所有注释。

 

2、去掉SQL文本前后的空格,TAB等字符。注意,是文本前面和后面的。中间的不会被去掉。

 

下面的三条SQL里,因为SELECT大小写的关系,最后一条和其他两条在QC里肯定是用的不一样的存储位置。而第一条和第二条,区别在于后者有个 注释,在不同客户端,会有不一样的结果。所以,保险起见,请尽量不要使用动态的注释。在PHP的mysql扩展里,SQL的注释是不会被去掉的。也就是三 条SQL会被存储在三个不同的缓存里,虽然它们的结果都是一样的。

 

  1. select * FROM people where name=’surfchen’;  
  2. select * FROM people where /*hey~*/name=’surfchen’;  
  3. SELECT * FROM people where name=’surfchen’; 

 

 

目前只有select语句会被cache,其他类似show,use的语句则不会被cache。

 

因为QC是如此前端,如此简单的一个缓存系统,所以如果一个表被更新,那么和这个表相关的SQL的所有QC都会被失效。假设一个联合查询里涉及到了表A和表B,如果表A或者表B的其中一个被更新(update或者delete),这个查询的QC将会失效。

也就是说,如果一个表被频繁更新,那么就要考虑清楚究竟是否应该对相关的一些SQL进行QC了。一个被频繁更新的表如果被应用了QC,可能会加重数 据库的负担,而不是减轻负担。一般的做法是默认打开QC,而对一些涉及频繁更新的表的SQL语句加上SQL_NO_CACHE关键词来对其禁用 CACHE。这样可以尽可能避免不必要的内存操作,尽可能保持内存的连续性。

那些查询很分散的SQL语句,也不应该使用QC。例如用来查询用户和密码的语句——“select pass from user where name=’surfchen’”。这样的语句,在一个系统里,很有可能只在一个用户登陆的时候被使用。每个用户的登陆所用到的查询,都是不一样的SQL 文本,QC在这里就几乎不起作用了,因为缓存的数据几乎是不会被用到的,它们只会在内存里占地方。

存储块

在本节里“存储块”和“block”是同一个意思。QC缓存一个查询结果的时候,一般情况下不是一次性地分配足够多的内存来缓存结果的。而是在查询 结果获得的过程中,逐块存储。当一个存储块被填满之后,一个新的存储块将会被创建,并分配内存(allocate)。

单个存储块的内存分配大小通过 query_cache_min_res_unit参数控制,默认为4KB。最后一个存储块,如果不能被全部利用,那么没使用的内存将会被释放。如果被缓 存的结果很大,那么会可能会导致分配内存操作太频繁,系统系能也随之下降;而如果被缓存的结果都很小,那么可能会导致内存碎片过多,这些碎片如果太小,就 很有可能不能再被分配使用。

除了查询结果需要存储块之外,每个SQL文本也需要一个存储块,而涉及到的表也需要一个存储块(表的存储块是所有线程共享的,每个表只需要一个存储 块)。存储块总数量=查询结果数量*2+涉及的数据库表数量。

也就是说,第一个缓存生成的时候,至少需要三个存储块:表信息存储块,SQL文本存储块,查 询结果存储块。而第二个查询如果用的是同一个表,那么最少只需要两个存储块:SQL文本存储块,查询结果存储块。

通过观察Qcache_queries_in_cache和Qcache_total_blocks可以知道平均每个缓存结果占用的存储块。它们的 比例如果接近1:2,则说明当前的query_cache_min_res_unit参数已经足够大了。如果Qcache_total_blocks比 Qcache_queries_in_cache多很多,则需要增加query_cache_min_res_unit的大小。

Qcache_queries_in_cache*query_cache_min_res_unit(sql文本和表信息所在的block占用的 内存很小,可以忽略)如果远远大于query_cache_size-Qcache_free_memory,那么可以尝试减小 query_cache_min_res_unit的值。

关于MySQL QueryCache原理 :调整大小

如果Qcache_lowmem_prunes增长迅速,意味着很多缓存因为内存不够而被释放,而不是因为相关表被更新。尝试加大query_cache_size,尽量使Qcache_lowmem_prunes零增长。

启动参数

show variables like ‘query_cache%’可以看到这些信息。

query_cache_limit:如果单个查询结果大于这个值,则不Cache

query_cache_size:分配给QC的内存。如果设为0,则相当于禁用QC。要注意QC必须使用大约40KB来存储它的结构,如果设定小于 40K

 

【编辑推荐】

  1. Oracle多表创建的视图insert的解决方法
  2. 阐述Oracle decode函数的用法
  3. 实现Oracle跨服务器的具体步骤
  4. Oracle释放undo表空间的实际操作步骤
  5. 实现Oracle 客户端配置的具体步骤
责任编辑:佚名 来源: 博客园
相关推荐

2010-05-27 17:17:37

Subversion入

2009-09-17 18:27:40

CLR是什么

2010-03-03 14:05:36

Python实例应用

2009-11-09 09:23:10

WCF数据契约

2009-09-18 10:40:05

CLR存储过程

2009-09-11 09:15:32

C# get set

2010-06-02 13:37:28

Linux IPv6配

2019-07-24 11:30:54

程序员技能开发者

2009-07-07 16:20:31

JSP试题

2021-05-31 07:01:46

限流算法令牌

2010-09-27 12:51:05

DHCP工作原理

2009-11-10 11:01:15

无线路由器设置

2009-11-19 15:01:58

2024-02-28 09:22:03

限流算法数量

2009-07-06 16:16:33

Servlet容器工作

2009-06-08 16:52:00

2019-10-24 11:10:06

Kubernetes网络运维

2010-05-25 13:34:18

MySQL命令

2010-11-22 16:22:39

MySQL连接查询

2009-10-27 09:30:53

VB.NET DLL搜
点赞
收藏

51CTO技术栈公众号