MySQL查询缓存是MySQL中一个突出功能,是查询优化的重要组成部分。了解其工作原理至关重要,因为它可能显著提升性能,或在某些情况下导致工作负载减慢。
MySQL查询缓存是全局共享的,供所有会话使用。它缓存SELECT查询及其结果集,使相同查询能从内存中快速获取数据。查询必须完全相同,包括无额外注释、空格或WHERE子句的细微差异。当执行SELECT查询时,如果缓存中存在,则直接从中读取;否则视为新查询,进入解析器处理。
尽管有优势,但MySQL查询缓存也有缺点。考虑这种情况:如果表频繁更新,会使该表的所有缓存查询失效。因此,对于“频繁更新表”,查询缓存的使用率可能很低,甚至无益。以下示例说明。
在MySQL中,查看状态如SHOW STATUS LIKE "qcache%";,初始显示缓存为空。随后执行SELECT * FROM d.t1;和SELECT * FROM d.t1 WHERE id=88995159;,查询被缓存,状态更新显示插入两个查询。
插入记录如INSERT INTO d.t1 (data) VALUES('Welcome');,会使缓存失效,内存回收,状态恢复初始。
接下来,讨论如何决定查询缓存大小。假设MySQL实例有两个表“t”(大量记录)和“t1”(少量记录)。重启后,query_cache_size为1MB,状态显示1MB空闲,无查询缓存。
执行SELECT * FROM d.t1;,查询缓存,第二次执行更快,Qcache_hits增1。
然后执行大表查询SELECT * FROM d.t WHERE id > 78995159;,导致Qcache_lowmem_prunes增1,表示缓存因空间不足而清除数据。随后小表查询需重新执行。
Qcache_lowmem_prunes表示MySQL清除缓存以腾空间的次数。需监控此变量,调整缓存大小直至其比率很低。
不宜将查询缓存设为过大如256MB,因为失效成本高。参考Peter Zaitsev的相关文章。
在多核CPU环境中,并发可能使查询缓存成为瓶颈而非助力。通常,除非工作负载证明有用,否则应关闭查询缓存。需深入了解环境以启用并决定大小。
若无相同查询机会,将query_cache_size和query_cache_type设为0。query_cache_type控制缓存,设为0减少查询执行开销。在高并发环境中,查询缓存互斥锁可能成瓶颈,设为0避免此问题,无法运行时启用缓存,从而降低开销。参考Percona Server的查询缓存增强。




苏公网安备32021302001419号