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

(转)看上去很美:MySQL Query Cache

 
阅读更多

当你的数据库打开了Query Cache(简称QC)功能后,数据库在执行SELECT语句时,会将其结果放到QC中,当下一次处理同样的SELECT请求时,数据库就会从QC取得结果,而不需要去数据表中查询

看上去很美:MySQL <wbr>Query <wbr>Cache

 

在这个“Cache为王的时代,我们总是通过不同的方式去缓存我们的结果从而提高响应效率,但一个缓存机制是否有效,效果如何,却是一个需要好好思考的问题。在MySQL中的Query Cache就是一个适用较少情况的缓存机制。在上图中,如果缓存命中率非常高的话,有测试表明在极端情况下可以提高效率238%[1]。但实际情况如何?Query Cache有如下规则,如果数据表被更改,那么和这个数据表相关的全部Cache全部都会无效,并删除之。这里数据表更改包括INSERTUPDATE,DELETETRUNCATEALTER TABLEDROP TABLE, or DROP DATABASE等。举个例子,如果数据表posts访问频繁,那么意味着它的很多数据会被QC缓存起来,但是每一次posts数据表的更新,无论更新是不是影响到了cache的数据,都会将全部和posts表相关的cache清除。如果你的数据表更新频繁的话,那么Query Cache将会成为系统的负担。有实验表明,糟糕时,QC会降低系统13%[1]的处理能力。

如果你的应用对数据库的更新很少,那么QC将会作用显著。比较典型的如博客系统,一般博客更新相对较慢,数据表相对稳定不变,这时候QC的作用会比较明显。

再如,一个更新频繁的BBS系统。下面是一个实际运行的论坛数据库的状态参数:

QCache_hit

5280438

QCache_insert

8008948

Qcache_not_cache

95372

Com select

8104159

可以看到,数据库一共往QC中写入了约800W次缓存,但是实际命中的只有约500W次。也就是说,每一个缓存的使用率约为0.66次。很难说,该缓存的作用是否大于QC系统所带来的开销。但是有一点是很肯定的,QC缓存的作用是很微小的,如果应用层能够实现缓存,将可以忽略QC的效果。

MySQL Query Cache

顾名思义,MySQL Query Cache 就是用来缓存和 Query 相关的数据的。具体来说,Query Cache 缓存了我们客户端提交给 MySQL  SELECT 语句以及该语句的结果集。大概来讲,就是将SELECT 语句和语句的结果做了一个 HASH 映射关系然后保存在一定的内存区域中。

在大部分的 MySQL 分发版本中,Query Cache 功能默认都是打开的,我们可以通过调整MySQL Server 的参数选项打开该功能。主要由以下5个参数构成:

·         query_cache_limit允许 Cache 的单条 Query 结果集的最大容量,默认是1MB,超过此参数设置的 Query 结果集将不会被 Cache

·         query_cache_min_res_unit设置 Query Cache 中每次分配内存的最小空间大小,也就是每个Query  Cache 最小占用的内存空间大小

·         query_cache_size设置 Query Cache 所使用的内存大小,默认值为0,大小必须是1024的整数倍,如果不是整数倍,MySQL 会自动调整降低最小量以达到1024的倍数

·         query_cache_type控制 Query Cache 功能的开关,可以设置为0(OFF),1(ON)2(DEMAND)三种,意义分别如下:

·         0(OFF):关闭 Query Cache 功能,任何情况下都不会使用 Query Cache

·         1(ON):开启 Query Cache 功能,但是当 SELECT 语句中使用的 SQL_NO_CACHE 提示后,将不使用Query Cache

·         2(DEMAND):开启 Query Cache 功能,但是只有当 SELECT 语句中使用了 SQL_CACHE提示后,才使用 Query Cache

·         query_cache_wlock_invalidate控制当有写锁定发生在表上的时刻是否先失效该表相关的 Query Cache,如果设置为 1(TRUE),则在写锁定的同时将失效该表相关的所有 Query Cache,如果设置为0(FALSE)则在锁定时刻仍然允许读取该表相关的 Query Cache

Query Cache 如何处理子查询的?
这是我遇到的最为常见的一个问题。其实Query Cache 是以客户端请求提交的Query 为对象来处理的,只要客户端请求的是一个 Query,无论这个 Query 是一个简单的单表查询还是多表 Join,亦或者是带有子查询的复杂 SQL,都被当作成一个 Query,不会被分拆成多个 Query 来进行 Cache。所以,存在子查询的复杂Query 也只会产生一个Cache对象,子查询不会产生单独的Cache内容。UNION[ALL] 类型的语句也同样如此。

Query Cache 是以 block 的方式存储的数据块吗?
不是,Query Cache 中缓存的内容仅仅只包含该 Query 所需要的结果数据,是结果集。当然,并不仅仅只是结果数据,还包含与该结果相关的其他信息,比如产生该 Cache 的客户端连接的字符集,数据的字符集,客户端连接的 Default Database等。

Query Cache 为什么效率会非常高,即使所有数据都可以 Cache 进内存的情况下,有些时候也不如使用 Query Cache 的效率高?
Query Cache
 的查找,是在MySQL 接受到客户端请求后在对 Query 进行权限验证之后,SQL 解析之前。也就是说,当 MySQL 接受到客户端的SQL后,仅仅只需要对其进行相应的权限验证后就会通过 Query Cache 来查找结果,甚至都不需要经过 Optimizer 模块进行执行计划的分析优化,更不许要发生任何存储引擎的交互,减少了大量的磁盘 IO  CPU 运算,所以效率非常高。

客户端提交的 SQL 语句大小写对 Query Cache 有影响吗?
有,由于 Query Cache 在内存中是以 HASH 结构来进行映射,HASH 算法基础就是组成 SQL 语句的字符,所以必须要整个 SQL 语句在字符级别完全一致,才能在 Query Cache 中命中,即使多一个空格也不行。

一个 SQL 语句在 Query Cache 中的内容,在什么情况下会失效?
为了保证 Query Cache 中的内容与是实际数据绝对一致,当表中的数据有任何变化,包括新增,修改,删除等,都会使所有引用到该表的 SQL  Query Cache 失效。

为什么我的系统在开启了 Query Cache 之后整体性能反而下降了?
当开启了 Query Cache 之后,尤其是当我们的 query_cache_type 参数设置为 1 以后,MySQL 会对每个SELECT 语句都进行 Query Cache 查找,查找操作虽然比较简单,但仍然也是要消耗一些 CPU 运算资源的。而由于 Query Cache 的失效机制的特性,可能由于表上的数据变化比较频繁,大量的Query Cache 频繁的被失效,所以Query Cache 的命中率就可能比较低下。所以有些场景下,Query Cache 不仅不能提高效率,反而可能造成负面影响。

如何确认一个系统的 Query Cache 的运行是否健康,命中率如何,设置量是否足够?
MySQL
 提供了一系列的Global Status 来记录Query Cache 的当前状态,具体如下:

·         Qcache_free_blocks目前还处于空闲状态的 Query Cache 中内存 Block 数目

·         Qcache_free_memory目前还处于空闲状态的 Query Cache 内存总量

·         Qcache_hitsQuery Cache 命中次数

·         Qcache_inserts Query Cache 中插入新的 Query Cache 的次数,也就是没有命中的次数

·         Qcache_lowmem_prunes Query Cache 内存容量不够,需要从中删除老的 Query Cache 以给新的 Cache 对象使用的次数

·         Qcache_not_cached没有被 Cache  SQL 数,包括无法被 Cache  SQL 以及由于query_cache_type 设置的不会被Cache  SQL

·         Qcache_queries_in_cache目前在 Query Cache 中的 SQL 数量

·         Qcache_total_blocksQuery Cache 中总的 Block 数量

根据简朝阳《mysql性能调优与架构设计》一书中表示Query cache的命中率是:
Qcache_hits / ( Qcache_hits + Qcache_inserts ) × 100%


可以根据这几个状态计算出 Cache 命中率,计算出 Query Cache 大小设置是否足够,总的来说,我个人不建议将 Query Cache 的大小设置超过256MB,这也是业界比较常用的做法。

 

http://blog.sina.com.cn/s/blog_6238358c01013efk.html

分享到:
评论

相关推荐

    UCenter info: MySQL Query Error SQL:SELECT value FROM [Table]vars WHERE noteexists

    SQL:SELECT value FROM [Table]vars WHERE name=’noteexists2′ UCenter info: MySQL Query Error SQL:SELECT value FROM [Table]vars WHERE name=’noteexists2′ Error:SELECT command denied to user ‘数据库...

    Mycat处理连接数据库8.0以上程序报错query_cache_size

    然而,当Mycat与MySQL 8.0及以上版本配合使用时,可能会遇到一些兼容性问题,其中“query_cache_size”报错就是典型的例子。 在MySQL 8.0中,查询缓存功能被默认禁用,并且在某些版本中被完全移除。这是由于MySQL...

    php提示Warning:mysql_fetch_array() expects的解决方法

    在mysql数据库连接时碰到Warning: mysql_fetch_array() expects …错误提示,根据我的经验这个是sql返回的query为空了,我们没有加己判断直接使用了. mysql_fetch_array()函数导致的,下面我们一起来看问题解决方案,我...

    PHP错误Warning:mysql_query()解决方法

    php提示错误:Warning: mysql_query() [function.mysql-query]: Access denied for user ‘ODBC’@’localhost’ (using password: NO) 代码: &lt;?php class mysqlClass { function mysqlClass($host='localhost...

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

    会发现其变量have_query_cache的值是yes,MYSQL初学者很容易以为这个参数为YES就代表开启了查询缓存,实际上是不对的,该参数表示当前版本的MYSQL是否支持Query Cache,实际上是否开启查询缓存是看另外一个参数的值:...

    解决mycatJDBC8驱动连接Mycat1.6报错 Unknown system variable 'query_cache_size'

    这个问题出现的原因在于MySQL 8.0版本中移除了`query_cache`相关的系统变量和功能,因此在使用新版本的JDBC驱动去连接旧版Mycat(可能基于较早版本的MySQL)时,会因找不到这个变量而抛出错误。 首先,我们需要理解...

    mysql-query-browser-1.1.18.tar.gz_mysql browser_mysql query brow

    MySQL Query Browser 1.1.18 是一个专为MySQL数据库设计的图形化查询工具,它为用户提供了直观且功能丰富的界面,以便于管理和查询数据库。这个软件版本1.1.18是开源的,意味着它的源代码是公开的,允许用户自由地...

    mysql-query-brower

    MySQL Query Browser是一款经典的数据库管理工具,它为MySQL数据库用户提供了一个直观、方便的界面来执行SQL查询、浏览数据、管理数据库对象以及执行其他数据库维护任务。虽然现在MySQL Workbench已经成为官方推荐的...

    对于mysql的query_cache认识的误区

    如果空格是加在query之前,比如是在query的起始处加了空格,这样是丝毫不影响query cache的结果的,mysql认为这是一条query, 而如果空格是在query中,那会影响query cache的结果,mysql会认为是不同的query

    MySQL Query Browser 图文说明

    MySQL Query Browser是一款强大的数据库管理工具,专为MySQL数据库设计,提供了直观的图形用户界面,使得数据库操作变得简单易行。本教程将详细讲解其主要功能和使用方法。 1. **安装与启动** - 安装MySQL Query ...

    MySQL Query Browser 1.1.rar

    MySQL Query Browser 1.1 是一个专为MySQL数据库设计的图形化查询工具,它提供了直观且用户友好的界面,使得数据库管理员和开发人员能够更轻松地进行SQL查询、数据库管理和数据浏览。这款软件的主要功能包括: 1. *...

    mysql query brower安装方法

    mysql query brower安装方法

    PHP100视频教程 10:MYSQL在PHP5中的应用

    说明:mysql_query用来根据连接标识符向该数据库服务器的当前数据库发送查询,如果连接标识符默认,则默认为是上一次打开的连接。返回值:成功后返回一个结果标识符,失败时返回false。$sql = "SELECT * FROM test...

    Mysql转oracle工具

    MySQL到Oracle转换是一个常见的任务,特别是在企业级应用迁移或整合过程中。这个工具专注于将MySQL的数据库结构和数据转换为Oracle数据库兼容的格式。下面将详细解释这个过程涉及的知识点。 1. **SQL语言的差异**:...

    PHP100视频教程 10:MYSQL在PHP5中的应用.rar

    $result = @ mysql_query($sql, $conn) or die(mysql_error()); 3、两种查询函数array / row区别 格式:mysql_fetch_row(result); 说明:mysql_fetch_row用来查询结果的一行保存至数组,该数组下标从0开始,每一...

    ROR绿色最新环境(2013/3/10)

    #&lt;ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x164feb&gt; Rack::Runtime Rack::MethodOverride ActionDispatch::RequestId Rails::Rack::Logger ActionDispatch::ShowExceptions ActionDispatch::...

    MySQL thread_cache和table_cache详解

    THREAD_CACHE MySQL里面为了提高客户端请求创建连接过程的性能,提供了一个连接池也就是 Thread_Cache池,将空闲的连接线程放在连接池中,而不是立即销毁.这样的好处就是,当又有一个新的请求的时候,mysql不会立即去创建...

    MySQL Query Browser

    MySQL Query Browser是一款由MySQL官方提供的图形化界面工具,主要用于帮助用户更加直观、便捷地管理和操作MySQL数据库。这个工具以其小巧的体积和免安装的特点,深受许多数据库管理员和开发者的喜爱。只需将压缩包...

    ansible-mysql-query:Ansible自定义模块,允许您在mysql数据库中设置值

    角色:mysql_query Ansible模块,用于在mysql表中设置值或插入记录。 对于将配置存储在数据库中的Web应用程序很有用。 例如,icingaweb2需要将初始用户插入数据库。 install-wizard可以做到,但是Ansible想要自动...

Global site tag (gtag.js) - Google Analytics