`
kiddwyl
  • 浏览: 402599 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

关于MySQL的查询缓存收

阅读更多
关于MySQL的查询缓存收
原理
QueryCache(下面简称QC)是根据SQL语句来cache的。一个SQL查询如果以select开头,那么MySQL服务器将尝试对其使用 QC。每个Cache都是以SQL文本作为key来存的。在应用QC之前,SQL文本不会被作任何处理。也就是说,两个SQL语句,只要相差哪怕是一个字符(例如大小写不一样;多一个空格等),那么这两个SQL将使用不同的一个CACHE。
不过SQL文本有可能会被客户端做一些处理。例如在官方的命令行客户端里,在发送SQL给服务器之前,会做如下处理:
过滤所有注释
去掉SQL文本前后的空格,TAB等字符。注意,是文本前面和后面的。中间的不会被去掉。
下面的三条SQL里,因为SELECT大小写的关系,最后一条和其他两条在QC里肯定是用的不一样的存储位置。而第一条和第二条,区别在于后者有个注释,在不同客户端,会有不一样的结果。所以,保险起见,请尽量不要使用动态的注释。在PHP的sql" onclick="tagshow(event)" class="t_tag">mysql扩展里,SQL的注释是不会被去掉的。也就是三条 SQL会被存储在三个不同的缓存里,虽然它们的结果都是一样的。
select * FROM people where name='surfchen';
select * FROM people where /*hey~*/name='surfchen';
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的值。
调整大小
如果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来存储它的结构,如果设定小于 40KB,则相当于禁用QC。QC存储的最小单位是1024 byte,所以如果你设定了一个不是1024的倍数的值,这个值会被四舍五入到最接近当前值的等于1024的倍数的值。
query_cache_type:0 完全禁止QC,不受SQL语句控制(另外可能要注意的是,即使这里禁用,上面一个参数所设定的内存大小还是会被分配);1启用QC,可以在SQL语句使用 SQL_NO_CACHE禁用;2可以在SQL语句使用SQL_CACHE启用。
query_cache_min_res_unit:每次给QC结果分配内存的大小
状态
show status like 'Qcache%'可以看到这些信息。
Qcache_free_blocks:当一个表被更新之后,和它相关的cache blocks将被free。但是这个block依然可能存在队列中,除非是在队列的尾部。这些blocks将会被统计到这个值来。可以用FLUSH QUERY CACHE语句来清空free blocks。
Qcache_free_memory:可用内存,如果很小,考虑增加query_cache_size
Qcache_hits:自mysql进程启动起,cache的命中数量
Qcache_inserts:自mysql进程启动起,被增加进QC的数量
Qcache_lowmem_prunes:由于内存过少而导致QC被删除的条数。加大query_cache_size,尽可能保持这个值0增长。
Qcache_not_cached:自mysql进程启动起,没有被cache的只读查询数量(包括select,show,use,desc等)
Qcache_queries_in_cache:当前被cache的SQL数量
Qcache_total_blocks:在QC中的blocks数。一个query可能被多个blocks存储,而这几个blocks中的最后一个,未用满的内存将会被释放掉。例如一个QC结果要占6KB内存,如果query_cache_min_res_unit是4KB,则最后将会生成3个 blocks,第一个block用来存储sql语句文本,这个不会被统计到query+cache_size里,第二个block为4KB,第三个 block为2KB(先allocate4KB,然后释放多余的2KB)。每个表,当第一个和它有关的SQL查询被CACHE的时候,会使用一个 block来存储表信息。也就是说,block会被用在三处地方:表信息,SQL文本,查询结果。

另外一篇:
如果 MySQL Server 负载比较高,处理非常繁忙的话,可以启动Query Cache 以加速响应时间,启动方法可以在my.cnf(Linux)或my.ini(Windows)中加入不以下项目:(Redhat下面是:/etc /my.cnf;Debian和Ubuntu是在/etc/mysql/my.cnf)
query_cache_size = 268435456
query_cache_type = 1
query_cache_limit = 1048576
以上语句的设置中 query_cache_size 是分配256M内存给Query Cache;query_cache_type=1,是给所有的查询做Cache;query_cache_limit 是指定个别的查询语句1MB的内存。
这些数据可以根据自己的需求作出适当的更改,设置完成之后,保存文档,重新启动MySQL即可。

query_cache_type 0 代表不使用缓冲, 1 代表使用缓冲,2 代表根据需要使用。
设置 1 代表缓冲永远有效,如果不需要缓冲,就需要使用如下语句:
SELECT SQL_NO_CACHE * FROM my_table WHERE ...
如果设置为 2 ,需要开启缓冲,可以用如下语句:
SELECT SQL_CACHE * FROM my_table WHERE ...
用 SHOW STATUS 可以查看缓冲的情况:
mysql> show status like 'Qca%';
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_queries_in_cache | 8 |
| Qcache_inserts | 545875 |
| Qcache_hits | 83951 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 2343256 |
| Qcache_free_memory | 33508248 |
| Qcache_free_blocks | 1 |
| Qcache_total_blocks | 18 |
+-------------------------+----------+
8 rows in set (0.00 sec)
如果需要计算命中率,需要知道服务器执行了多少 SELECT 语句:
mysql> show status like 'Com_sel%';
+---------------+---------+
| Variable_name | Value |
+---------------+---------+
| Com_select | 2889628 |
+---------------+---------+
1 row in set (0.01 sec)
在本例中, MySQL 命中了 2,889,628 条查询中的 83,951 条,而且 INSERT 语句只有 545,875 条。因此,它们两者的和和280万的总查询相比有很大差距,因此,我们知道本例使用的缓冲类型是 2 。

而在类型是 1 的例子中, Qcache_hits 的数值会远远大于 Com_select 。
分享到:
评论

相关推荐

    清空mysql 查询缓存的可行方法

    在MySQL数据库系统中,查询缓存是一个非常重要的性能优化机制,它允许服务器存储先前执行的SQL查询及其结果,以便在后续请求相同查询时快速返回结果,而无需再次解析和执行查询。然而,这也可能导致某些情况下优化...

    mysql 设置查询缓存

    可将如下语句 query_cache_size = 268435456 query_cache_type = 1 query_cache_limit = 1048576 存放到/etc/my.cnf文件的[mysqld]下 然后重启mysql数据库 service mysqld restart 就会启动mysql的缓存机制Query ...

    Mysql查询流程分析

    如果之后有相同的查询再次执行,MySQL可以直接从缓存中获取结果而无需重新执行查询,从而大大提高了查询速度。然而,需要注意的是,查询缓存的使用可能会受到某些因素的影响,例如缓存空间大小限制以及缓存失效策略...

    MySQL缓存的查询和清除命令使用详解

    Mysql 查询缓存 查询缓存的作用就是当查询接收到一个和之前同样的查询,服务器将会从查询缓存种检索结果,而不是再次分析和执行上次的查询。这样就大大提高了性能,节省时间。 1.配置查询缓存 修改配置文件,修改...

    PHP查询缓存.doc

    当数据查询结果被缓存后,可以避免频繁地连接数据库、构建和执行查询,从而缩短响应时间。尤其是对于远程数据库或需要处理大量数据的情况,缓存能显著改善性能。 在PHP中,通常使用的数据库是MySQL,因此开发者需要...

    MySQL的查询缓存机制基本学习教程

    MySQL的查询缓存机制是一种优化策略,用于提高数据库性能,特别是对于那些经常被重复执行但结果不变的SQL查询。查询缓存将SQL语句及其结果存储在内存中,当同样的查询再次执行时,MySQL可以直接从缓存中获取结果,...

    基于MySQL的高可靠性缓存DNS系统的设计与实现.pdf

    检查模块负责监控和过滤DNS查询请求,缓存模块将接收到的DNS信息存储在MySQL数据库中,而转发模块则根据缓存情况决定是否直接从数据库返回结果或向其他DNS服务器进行查询。 为了实现这个系统,作者基于BIND(目前最...

    MySQL 5.1 版数据库

    - **查询缓存**:MySQL 5.1增强了查询缓存功能,能够存储已执行过的SQL语句及其结果,当相同的查询再次出现时,可以直接从缓存中获取结果,提升查询速度。 - **InnoDB引擎优化**:InnoDB是MySQL中最常用的事务处理...

    mybatis+redis缓存配置

    ### MyBatis与Redis缓存配置详解 #### 一、MyBatis缓存机制概述 在MyBatis中,缓存是一项重要的性能优化措施。它能够显著减少数据库的访问次数,提高应用程序的响应速度。MyBatis提供了两种级别的缓存支持:一级...

    MySQL高速缓存启动方法及参数详解(query_cache_size)

    MySQL的高速缓存,也称为查询缓存(Query Cache),是一种优化机制,它可以在数据库接收到相同的SELECT查询时,直接返回之前缓存的结果,而无需再次执行查询操作。这极大地提高了查询性能,尤其是在处理大量重复查询...

    万字总结:学习MySQL优化原理,这一篇就够了!

    当接收到一个查询请求时,MySQL首先会检查该查询是否已存在于缓存中。若命中,则直接返回缓存结果,无需执行查询。但需要注意的是,查询缓存也有其局限性: - 缓存数据的有效性依赖于底层表的状态。一旦表的数据或...

    mysql安装包mysql5.0

    9. **性能优化**:通过优化查询缓存、线程池等机制,提升了整体性能,尤其是对于高并发的读取操作。 10. **XML支持**:MySQL 5.0支持XML数据类型和函数,方便XML数据的存储和处理。 在安装MySQL 5.0时,`Setup.exe...

    高性能MySQL.pdf

    通过监控MySQL的性能指标,如查询缓存命中率、磁盘I/O、CPU使用率等,可以及时发现潜在问题。书中可能介绍各种监控工具和诊断方法。 总的来说,《高性能MySQL》全面介绍了MySQL的各个方面,旨在帮助读者提升数据库...

    mysql 5.5版 mysql.h.rar

    同时,引入了更好的查询缓存机制,允许服务器更快地响应先前执行过的相同查询,提升了整体性能。 此外,5.5版还增加了对分区表的支持,允许用户将大型表分成更小、更易管理的部分。这有助于提高查询性能,尤其是在...

    mysql优化

    它可以提供关于查询计划的详细信息,包括索引的使用情况、数据表的扫描方式等。这对于识别查询或表结构中的性能瓶颈至关重要。 **2. 示例分析** 假设有一个包含多表连接的复杂查询,可以通过在查询前添加`EXPLAIN`...

    接收NetFlow数据并导入Mysql数据库的Java工具

    此外,工具还提供了对存入数据的简单分析功能,这可能是通过执行SQL查询或者在Java代码中实现的统计计算来实现的。用户可以通过这个特性快速了解网络流量情况,如最大流量、最繁忙的IP对、异常流量等。 标签...

    mysql巡检报告.pdf

    * 检查点:检查 MySQL 数据库请求缓存命中,包括请求缓存命中、请求缓存大小和请求缓存限制 * 检查方法:使用 SHOW STATUS LIKE ‘Qcache%’ 命令查看请求缓存命中 * 结果解释:检查结果正常,Qcache_lowmem_prune ...

    4.mysql dbutils c3p0 缓存池工具类

    总结起来,"4.mysql dbutils c3p0 缓存池工具类"这个主题涉及了如何在Java项目中使用MySQL数据库,以及如何通过DBUtils和C3P0来简化数据库操作和管理数据库连接。DBUtils提供了一套实用的数据库操作API,而C3P0则...

    关于MySql的监控

    ### 关于MySQL的监控 #### 一、监控的目标 MySQL监控的主要目标在于实时掌握数据库的运行状况,确保系统的稳定性和高效性。具体来说,包括以下几个方面: 1. **快速获得MySQL运行状态**:通过监控系统可以迅速...

Global site tag (gtag.js) - Google Analytics