mysql Query Cache 默认为打开。从某种程度能够提升查询的效果,可是未必是最优的解决方案,若是有的大量的修改和查询时,因为修改形成的cache失效,会给服务器形成很大的开销,能够经过query_cache_type【0(OFF)1(ON)2(DEMAND)】来控制缓存的开关.mysql
须要注意的是mysql query cache 是对大小写敏感的,由于Query Cache 在内存中是以 HASH 结构来进行映射,HASH 算法基础就是组成 SQL 语句的字符,因此 任何sql语句的改变从新cache,这也是项目开发中要创建sql语句书写规范的缘由吧算法
1. 什么时候cache
a) mysql query cache内容为 select 的结果集, cache 使用完整的 sql 字符串作 key, 并区分大小写,空格等。即两个sql必须彻底一致才会致使cache命中。
b) prepared statement永远不会cache到结果,即便参数彻底同样。听说在 5.1 以后会获得改善。
c) where条件中如包含了某些函数永远不会被cache, 好比current_date, now等。
d) date 之类的函数若是返回是以小时或天级别的,最好先算出来再传进去。
select * from foo where date1=current_date -- 不会被 cache
select * from foo where date1='2008-12-30' -- 被cache, 正确的作法
e) 太大的result set不会被cache (< query_cache_limit)sql
2. 什么时候invalidate
a) 一旦表数据进行任何一行的修改,基于该表相关cache当即所有失效。
b) 为何不作聪明一点判断修改的是否cache的内容?由于分析cache内容太复杂,服务器须要追求最大的性能。数据库
3. 性能
a) cache 未必全部场合老是会改善性能
当有大量的查询和大量的修改时,cache机制可能会形成性能降低。由于每次修改会致使系统去作cache失效操做,形成不小开销。
另外系统cache的访问由一个单一的全局锁来控制,这时候大量>的查询将被阻塞,直至锁释放。因此不要简单认为设置cache一定会带来性能提高。
b) 大result set不会被cache的开销
太大的result set不会被cache, 但mysql预先不知道result set的长度,因此只能等到reset set在cache添加到临界值 query_cache_limit 以后才会简单的把这个cache 丢弃。这并非一个高效的操做。若是mysql status中Qcache_not_cached太大的话, 则可对潜在的大结果集的sql显式添加 SQL_NO_CACHE 的控制。
query_cache_min_res_unit = (query_cache_size – Qcache_free_memory) / Qcache_queries_in_cache缓存
4. 内存池使用
mysql query cache 使用内存池技术,本身管理内存释放和分配,而不是经过操做系统。内存池使用的基本单位是变长的block, 一个result set的cache经过链表把这些block串起来。由于存放result set的时候并不知道这个resultset最终有多大。block最短长度为 query_cache_min_res_unit, resultset 的最后一个block会执行trim操做。服务器
Query Cache 在提升数据库性能方面具备很是重要的做用。函数
其设定也很是简单,仅须要在配置文件写入两行: query_cache_type 和 query_cache _size,并且 MySQL 的 query cache 很是快!并且一旦命中,就直接发送给客户端,节约大量的 CPU 时间。性能
固然,非 SELECT 语句对缓冲是有影响的,它们可能使缓冲中的数据过时。一个 UPDATE 语句引发的部分表修改,将致使对该表全部的缓冲数据失效,这是 MySQL 为了平衡性能而没有采起的措施。由于,若是每次 UPDATE 须要检查修改的数据,而后撤出部分缓冲将致使代码的复杂度增长。spa
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%'; |
若是须要计算命中率,须要知道服务器执行了多少 SELECT 语句:
代码以下 | 复制代码 |
mysql> show status like 'Com_sel%'; |
在本例中, MySQL 命中了 2,889,628 条查询中的 83,951 条,并且 INSERT 语句只有 545,875 条。所以,它们二者的和和280万的总查询相比有很大差距,所以,咱们知道本例使用的缓冲类型是 2 。
而在类型是 1 的例子中, Qcache_hits 的数值会远远大于 Com_select