为了提高查询速度,Mysql会维护一个内存区域(官方文档指出,大小至少41984B)对查询结果进行缓存,当查询时发现缓存区里有数据则直接返回结果而不用去执行sql语句。

查询命中的条件

  每个缓存查询至少需要两个块(一个块用于查询文本,一个或多个块用于查询结果)。并且,每一个查询使用的每个表需要一个块。但是,如果两个或多个查询使用相同的表,仅需要分配一个块。

  对于两个查询语句是否相同的判定,Mysql是比较严格,查询必须是完全相同的(逐字节相同)才能够被认为是相同的。另外,同样的查询字符串由于其它原因可能认为是不同的。使用不同的数据库、不同的协议版本或者不同 默认字符集的查询被认为是不同的查询并且分别进行缓存。例如,以下两个查询是不相同的:

SELECT * FROM tbl_name
Select * from tbl_name

缓冲区配置

  在Mysql中,设置缓冲区大小命令为:

 mysql>SET GLOBAL query_cache_size = 41984;

  如果设置的query_cache_size小于41984,则会设置失败,并自动把它置为0。如果设置为0则表示不使用缓冲区。

  当query_cache_size大于0的情况下,并不能保证缓冲区会被使用,还必须根据变量query_cache_type来决定,该变量有3中状态,分别代表3中不同缓冲方式:

  • 0或OFF--------将阻止缓存或查询缓存结果。
  • 1或ON---------将允许缓存,以SELECT SQL_NO_CACHE开始的查询语句除外。
  • 2或DEMAND--------仅对以SELECT SQL_CACHE开始的那些查询语句启用缓存。

  设置方式如下:

mysql> SET SESSION query_cache_type = OFF;

  

查询结果的内存大小分配  

  要控制可以被缓存的具体查询结果的最大值,应设置query_cache_limit变量。 默认值是1MB。

当一个查询结果(返回给客户端的数据)从查询缓冲中提取期间,它在查询缓存中排序。因此,数据通常不在大的数据块中处理。查询缓存根据数据排序要求分配数据块,因此,当一个数据块用完后分配一个新的数据块。因为内存分配操作是昂贵的(费时的),所以通过query_cache_min_res_unit系统变量给查询缓存分配最小值。当查询执行时,最新的结果数据块根据实际数据大小来确定,因此可以释放不使用的内存。根据你的服务器执行查询的类型,你会发现调整query_cache_min_res_unit变量的值是有用的:

  • query_cache_min_res_unit默认值是4KB。这应该适合大部分情况。
  • 如果你有大量返回小结果数据的查询,默认数据块大小可能会导致内存碎片,显示为大量空闲内存块。由于缺少内存,内存碎片会强制查询缓存从缓存内存中修整(删除)查询。这时,你应该减少query_cache_min_res_unit变量的值。空闲块和由于修整而移出的查询的数量通过Qcache_free_blocks和Qcache_lowmem_prunes变量的值给出。
  • 如果大量查询返回大结果(检查 Qcache_total_blocks和Qcache_queries_in_cache状态变量),你可以通过增加query_cache_min_res_unit变量的值来提高性能。但是,注意不要使它变得太大。

  也就是说,则给查询结果分配缓冲区大小时,并不是再等待查询结果返回后根据结果大小来分配空间,而是先根据query_cache_min_res_unit分配一个内存,待结果返回后直接放入内存中。这时候分3种情况考虑:

  1. 如果(查询结果的大小=query_cache_min_res_unit),则直接把结果存入到该缓冲区中。
  2. 如果(查询结果的大小<query_cache_min_res_unit),则直接把结果存入到该缓冲区中,然后把多分配的空间释放掉,这种情况容易产生内存碎片。
  3. 如果(查询结果的大小>query_cache_min_res_unit),则需要再分配内存空间来存放结果

查询高速缓冲状态和维护

  可以使用下面的语句检查MySQL服务器是否提供查询缓存功能:

mysql> SHOW VARIABLES LIKE 'have_query_cache';

+------------------+-------+

| Variable_name    | Value |

+------------------+-------+

| have_query_cache | YES   |

+------------------+-------+

可以使用FLUSH QUERY CACHE语句来清理查询缓存碎片以提高内存使用性能。该语句不从缓存中移出任何查询。

RESET QUERY CACHE语句从查询缓存中移出所有查询。FLUSH TABLES语句也执行同样的工作。

为了监视查询缓存性能,使用SHOW STATUS查看缓存状态变量:

mysql> SHOW STATUS LIKE 'Qcache%';
+-------------------------+--------+
|变量名                   |值 |
+-------------------------+--------+
| Qcache_free_blocks      | 36     |
| Qcache_free_memory      | 138488 |
| Qcache_hits             | 79570  |
| Qcache_inserts          | 27087  |
| Qcache_lowmem_prunes    | 3114   |
| Qcache_not_cached       | 22989  |
| Qcache_queries_in_cache | 415    |
| Qcache_total_blocks     | 912    |
+-------------------------+--------+

清除缓冲区释放空间
  查询缓存使用长度可变块,因此Qcache_total_blocks和Qcache_free_blocks可以显示查询缓存内存碎片。执行FLUSH QUERY CACHE后,只保留一个空闲块。
mysql>FLUSH QUERY CACHE;

内存置换策略

查询缓冲区使用最近最少使用(LRU)策略来确定哪些查询从缓冲区中移出(根据Qcache_lowmem_prunes状态变量提供的信息能够帮助你你调整查询缓存的大小。它计算为了缓存新的查询而从查询缓冲区中移出到自由内存中的查询的数目

 

Mysql查询高速缓存区的更多相关文章

  1. mysql查询缓存打开、设置、参数查询、性能变量意思

    http://blog.sina.com.cn/s/blog_75ad10100101by7j.html http://www.cnblogs.com/zemliu/archive/2013/08/0 ...

  2. MySQL查询性能优化(精)

    MySQL查询性能优化 MySQL查询性能的优化涉及多个方面,其中包括库表结构.建立合理的索引.设计合理的查询.库表结构包括如何设计表之间的关联.表字段的数据类型等.这需要依据具体的场景进行设计.如下 ...

  3. 170727、MySQL查询性能优化

    MySQL查询性能优化 MySQL查询性能的优化涉及多个方面,其中包括库表结构.建立合理的索引.设计合理的查询.库表结构包括如何设计表之间的关联.表字段的数据类型等.这需要依据具体的场景进行设计.如下 ...

  4. MySQL查询高速缓冲

    对mysql的优化不在行,搞过几次优化,但是都不是很理想,还是浪费资源太多.一直发现我的mysql的缓存命中率极差,情况良好的时候到达过60-70%,但是运行时间一长,只有10-20%.查了一些资料, ...

  5. 【转】MySQL查询缓存详解

    [转]MySQL查询缓存详解 转自:https://www.cnblogs.com/Alight/p/3981999.html 相关文章:http://www.zsythink.net/archive ...

  6. MySQL查询缓存详解(总结)

    MySQL查询缓存详解(总结) 一.总结 一句话总结: mysql查询缓存还是可以用用试一试,但是更推荐分布式,比如redis/memcache之流,将数据库中查询的数据和查询语句以键值对的方式存进分 ...

  7. mysql查询缓存简单使用

    MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品.MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBM ...

  8. mysql查询性能优化

    mysql查询过程: 客户端发送查询请求. 服务器检查查询缓存,如果命中缓存,则返回结果,否则,继续执行. 服务器进行sql解析,预处理,再由优化器生成执行计划. Mysql调用存储引擎API执行优化 ...

  9. Mysql查询——深入学习

    1.开篇 之前上一篇的随笔基本上是单表的查询,也是mysql查询的一个基本.接下来我们要看看两个表以上的查询如何得到我们想要的结果. 在学习的过程中我们一起进步,成长.有什么写的不对的还望可以指出. ...

随机推荐

  1. [android]android开发中的运行错误之:adb.exe

    调试的时候出现一下错误: The connection to adb is down, and a servera error has occured.You must restart adb and ...

  2. URL锚点定位

    我们都知道<a>标签中的url属性有三种值: 绝对 URL - 指向另一个站点(比如 href="http://www.example.com/index.htm") ...

  3. postgresql赋予/撤消 用户权限

    (1)给予权限:grant           grant select on 表名 to 用户名: (2)撤消权限:revoke           revoke select on 表名 from ...

  4. 异常处理与调试5 - 零基础入门学习Delphi54

    调试(Debug) 让编程改变世界 Change the world by program [caption id="attachment_2731" align="al ...

  5. Custom.pm

    1) 只有一种事情比你培训员工.培养员工然后他们离开要更糟糕,那就是你不培训他们.不培养他们,但他们仍然留下来. 2) PM的含义: Product Manager, Project Manager, ...

  6. Material风格的Quick组件,妈妈再也不用担心我的界面不好看了

    https://github.com/papyros/qml-material http://www.zhihu.com/question/38523930

  7. Apache Commons Pool 故事一则

    Apache Commons Pool 故事一则 最近工作中遇到一个由于对commons-pool的使用不当而引发的问题,习得正确的使用姿势后,写下这个简单的故事,帮助理解Apache Commons ...

  8. LeeCode(Database)-Duplicate Emails

    Write a SQL query to find all duplicate emails in a table named Person. +----+---------+ | Id | Emai ...

  9. python爬虫系列之爬京东手机数据

    python抓京东手机数据 作者:vpoet mail:vpoet_sir@163.com #coding=utf-8 import urllib2 from lxml import etree im ...

  10. http的无状态无连接到底是什么含义

    无连接:服务器处理完客户的请求,并收到客户的应答后,即断开连接. 早期这么做的原因是 HTTP协议产生于互联网,因此服务器需要处理同时面向全世界数十万.上百万客户端的网页访问,但每个客户端(即浏览器) ...