您应该仅使用以下命令禁用查询缓存
[mysqld]
query_cache_size = 0
然后重启mysql。我为什么建议呢?
查询缓存将始终与InnoDB对接。如果InnoDB的MVCC允许修改不影响其他事务的可重复读取,则允许InnoDB的MVCC从查询缓存中为查询提供服务。不幸的是,InnoDB只是不这样做。显然,您有很多查询会很快失效,并且可能不会被重用。
对于MySQL 4.0下的InnoDB,查询缓存被禁用了。对于MySQL 4.1+,当允许按表访问查询缓存时,InnoDB会扮演交通警察。
从您的问题的角度来看,我想说删除查询缓存的理由并不仅仅是开销,而是InnoDB如何管理它。
有关InnoDB如何与查询缓存进行交互的更多信息,请阅读“高性能MySQL(第二版)”一书的第213-215页。
如果您的全部或大部分数据都是MyISAM,则可以使用使用SQL_NO_CACHE的原始想法。
如果您混合使用InnoDB和MyISAM,则必须根据缓存未命中的数量为应用程序找到合适的平衡。实际上,同一本书的第209-210页指出了缓存未命中的原因:
- 该查询不可缓存,原因是该查询包含不确定的构造(例如CURRENT_DATE),或者其结果集太大而无法存储。这两种不可缓存的查询都会增加Qcache_not_cached状态变量。
- 服务器以前从未见过该查询,因此它永远没有机会缓存其结果。
- 查询的结果先前已被缓存,但是服务器将其删除。之所以会发生这种情况,是因为没有足够的内存来保留它,或者是有人指示服务器删除它,或者是因为它已失效。
高速缓存未命中且很少有不可缓存查询的根本原因可能是:
- 查询缓存尚未启动。那是服务器没有机会用结果集填充缓存。
- 服务器正在查看以前未曾查询过的查询。如果没有很多重复查询,即使在预热缓存后也可能发生。
- 有很多缓存失效。
更新2012-09-06 10:10 EDT
查找最新更新的信息,您已query_cache_limit
设置为1048576(1M)。这会将任何结果集限制为1M。如果您检索到更大的东西,它将根本不会被缓存。虽然你已经query_cache_size
设置到104857600(100M),这仅允许在一个完美的世界设定100个缓存的结果。如果执行数百个查询,则碎片会很快出现。您还有4096(4K)作为最小大小结果集。不幸的是,mysql没有用于对查询缓存进行碎片整理的内部机制。
如果必须具有查询缓存,并且具有大量RAM,则可以执行以下操作:
SET GLOBAL query_cache_size = 0;
SELECT SLEEP(60);
SET GLOBAL query_cache_size = 1024 * 1024 * 1024;
为了清除查询缓存。您会丢失所有缓存的结果,因此请在非高峰时间运行这些行。
我还将分配以下内容:
- query_cache_size = 1G
- query_cache_limit = 8M
剩下23G的RAM。我要提出以下几点:
- innodb_buffer_pool_size = 12G
- key_buffer_size = 4G
剩下7G。这对于OS和DB连接应该足够了。
请记住,关键缓冲区仅缓存MyISAM索引页,而InnoDB缓冲池则缓存数据和索引。
另一个建议:升级到MySQL 5.5,以便您可以为多个CPU和多个线程配置InnoDB以进行读/写I / O。
请参阅我之前有关将MySQL 5.5与访问InnoDB的多个CPU结合使用的文章
更新2012-09-06 14:56 EDT
我清除查询缓存的方法相当极端,因为它可以缓冲缓存的数据并形成一个完全不同的RAM段。正如您在评论中指出的那样FLUSH QUERY CACHE
(如您所建议),甚至RESET QUERY CACHE
会更好。为了澄清起见,当我说“没有内部机制”时,我的意思就是。碎片整理是必需的,必须手动完成。需要crontab'd。
如果您在InnoDB上比在MyISAM上更频繁地执行DML(INSERT,UPDATE,DELETE),我会说完全删除了查询缓存,这是我在一开始就说过的。