MySQL 查詢緩存(Query Cache)在 5.7 仍可用、8.0 已移除。本文深度剖析其命中條件(Hash 表 Key 構成)、工作流程、失效觸發條件、記憶體塊管理與碎片問題、InnoDB 事務隔離下的緩存可見性規則、配置參數與監控指標解讀,並附實測驗證案例。
NOW(), RAND(), UUID(), CURRENT_DATE())的查詢不緩存、不命中。INSERT/UPDATE/DELETE/TRUNCATE/ALTER/DROP TABLE/DATABASE 觸發該表所有緩存條目失效。LOCK TABLES 視 query_cache_wlock_invalidate 設定。query_cache_limit 不緩存。query_cache_size(預設 0,關閉),約 40KB 用於元數據。query_cache_min_res_unit(預設 4KB)。Qcache_lowmem_prunes 增長。FLUSH QUERY CACHE(阻塞其他連接使用緩存)。RESET QUERY CACHE。SELECT ... LOCK IN SHARE MODE, FOR UPDATE)不使用緩存。SHOW VARIABLES LIKE '%query_cache%';
| 參數 | 含義 | 建議 |
|---|---|---|
query_cache_type | OFF/ON/DEMAND | 讀多寫少開 ON,寫多關 OFF |
query_cache_size | 總記憶體 (bytes, 1024 倍數) | 64M~256M,視命中率調整 |
query_cache_limit | 單查詢最大緩存 | 1M~4M |
query_cache_min_res_unit | 最小塊大小 | 大結果集調大 (16K~64K) |
query_cache_wlock_invalidate | 鎖表時是否仍返緩存 | OFF |
SHOW STATUS LIKE 'Qcache%';
| 指標 | 健康判斷 |
|---|---|
Qcache_hits / Qcache_inserts > 3:1 | 緩存有效 |
> 10:1 | 緩存優秀 |
Qcache_lowmem_prunes 持續增長 | 記憶體不足/碎片嚴重 |
Qcache_free_blocks 過大 | 碎片多,需 FLUSH QUERY CACHE |
SET GLOBAL query_cache_size = 600000; SET SESSION query_cache_type = ON; USE test; SELECT COUNT(*) FROM animals; -- 首次執行 SHOW STATUS LIKE 'Qcache_hits'; -- 0 SELECT COUNT(*) FROM animals; -- 二次執行 SHOW STATUS LIKE 'Qcache_hits'; -- 1 (命中) INSERT INTO animals VALUES (9, 'test'); -- 寫入導致失效 SELECT COUNT(*) FROM animals; -- 再次執行 SHOW STATUS LIKE 'Qcache_hits'; -- 仍為 1 (未命中,重新執行) SELECT COUNT(*) FROM animals; -- 三次執行 SHOW STATUS LIKE 'Qcache_hits'; -- 2 (命中新緩存)
查詢緩存以「精確 SQL 匹配 + 表級失效」為核心,適合「靜態數據、高頻重複查詢、結果集小」場景。InnoDB MVCC 與加鎖讀繞過緩存,保證一致性。MySQL 8.0 移除後,建議遷移至應用層/中間件緩存架構,配合 PreparedStatement 與讀寫分離,獲得更可控、可擴展的效能提升。