Query Cache 核心機制與實戰指南
MySQL Query Cache 將 SELECT 結果集與 SQL 文本鍵值對緩存,命中時跳過解析、優化、執行直接返回。但其「完全匹配」判斷機制、全域鎖爭用、碎片化等特性,導致高併發寫入場景下往往得不償失。
工作原理與不可快取場景
- 大小寫敏感、字面值完全一致才命中 (含空格、註解)。
- 不可快取:含
SQL_NO_CACHE、不確定性函數 (NOW(), RAND(), UUID() 等)、系統表、用戶變數/存儲過程局部變數、LOCK IN SHARE MODE/FOR UPDATE、SELECT ... INTO、事務隔離級別 SERIALIZABLE、臨時表、有警告的查詢、不涉及表的查詢、列級權限查詢。
核心配置參數
| 參數 | 建議值 | 說明 |
| query_cache_type | 0 (關閉) / 2 (DEMAND) | 0=關閉;1=全開;2=需 SQL_CACHE 顯式啟用。生產建議 0 或 2。 |
| query_cache_size | 64M~128M | 總記憶體上限,非越大越好,過大增加鎖爭用與碎片掃描開銷。 |
| query_cache_limit | 16K~1M | 單個結果集上限,防止大結果集佔滿快取。 |
| query_cache_min_res_unit | 1K~16K | 記憶體分配最小單元,過大產生碎片,過小增加分配次數。 |
| query_cache_wlock_invalidate | 0 (預設) | MyISAM 寫鎖期間是否允許讀快取。0=允許讀舊快取;1=等待鎖釋放。 |
維護操作
FLUSH QUERY CACHE:整理碎片,不清除資料。
RESET QUERY CACHE / FLUSH TABLES:完全清空快取。
- DDL/DML 自動失效相關表快取,持有全域鎖,高寫入場景易成熱點。
關鍵監控指標與判讀
| 指標 | 公式 | 健康閾值 | 異常含義 |
| 碎片率 | Qcache_free_blocks / Qcache_total_blocks × 100% | < 20% | 需 FLUSH QUERY CACHE |
| 命中率 | (Qcache_hits - Qcache_inserts) / Qcache_hits × 100% | > 80% | < 40% 考慮關閉或縮小 |
| 記憶體使用率 | (query_cache_size - Qcache_free_memory) / query_cache_size × 100% | 60%~80% | 長期 100% 且 Qcache_lowmem_prunes 持續增長 → 擴容 |
| 低記憶體剔除 | Qcache_lowmem_prunes | 平穩或緩增 | 暴增說明快取太小或碎片嚴重 |
適用業務場景判斷樹
- 系統讀多寫少 (門戶、新聞、報表、論壇)。
- 查詢語句高度重複 (相同參數、相同 SQL)。
- 涉及表DML 頻率低 (減少快取失效與鎖爭用)。
- 可接受最終一致性 (快取資料可能略舊)。
- → 滿足上述條件,建議
query_cache_type=2 + SQL_CACHE 顯式控制。
生產環境決策建議
- MySQL 5.7 起已棄用,8.0 移除 Query Cache。新架構請勿依賴。
- 現有系統若命中率高、寫入低,可暫時保留;規劃遷移至 Redis / 應用層快取 / 物化視圖。
- 寫入密集型系統 (電商、即時通訊、日誌) 直接關閉 (query_cache_type=0),避免全域鎖拖垮吞吐。