Powered by Typecho)))
Optimized by EAimTY
最开始在面对一个200W行的表的时候开始遇到Query Cache, 现在看到了High Performance MySQL这本书,学习了一下,有了以下的总结,
原文地址:http://www.renwenyue.com/2008/12/mys...-scenario.html
1.MySQL如何生成Query Cache
* MySQL Query Cache是内容为 select 的Key=>Value ResultSet, Cache 使用完整的SQL字符串做 key, 并区分大小写,空格等,两个SQL必须完全一致才会导致Cache命中.
* prepared statement永远不会cache到结果,即使参数完全一样.据说在 5.1 之后可能会改善(慎用mysqli的stmt和prepare)
* where条件中如包含了某些函数永远不会被cache, 比如current_date, now等.
* date 之类的函数如果返回是以小时或天级别的,最好先算出来再传进去(和做主从的时候尽量不要now一样)
select * from Table where time=current_date -- 不会被 cache
select * from Table where time='2000-01-01' -- 被cache, 正确的做法
* 太大的result set不会被cache (取决于query_cache_limit)
2.Query Cache如何失效
一旦表数据进行任何一行的修改,基于该表相关cache立即全部失效.
3.Query Cache的性能
* cache 未必所有场合都能改善性能
当有大量的查询和大量的修改时,cache机制可能会造成性能下降.因为每次修改会导致系统去做cache失效操作,造成不小开销.
另外系统cache的访问由一个单一的全局锁来控制,这时候大量>的查询将被阻塞,直至锁释放.所以不要简单认为设置cache必定会带来性能提升.
* 太大的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.Query Cache的内存池使用
mysql query cache 使用内存池技术,不是通过操作系统,而是自己管理内存释放和分配.内存池使用的基本单位是变长的block, 一个result set的cache通过链表把这些block串起来.因为存放result set的时候并不知道这个resultset最终有多大.block最短长度为 query_cache_min_res_unit, resultset 的最后一个block会执行trim操作.
定长:空间浪费
变长:需清理碎片
block 小: 链表超长,访问大块数据效率低。
参考文章:
High Performance MySQL
High Performance MySQL中有关mysql query cache的说明
MySQL的Query Cache