MySQL Query Cache (QC) 在解析前攔截 SELECT,以 SQL 文本為 Key (Byte-by-byte 完全匹配) 緩存完整結果集。雖然 8.0 已移除,但在 5.6/5.7 存量系統中仍廣泛存在,理解其機制對遷移決策與歷史系統維護至關重要。
SELECT 文本 + 數據庫名 + 客戶端字符集 + 其他會話變量 → 精確二進制匹配。大小寫、空格、註釋、換行均導致不同 Key。INSERT/UPDATE/DELETE/TRUNCATE/ALTER) 導致該表相關所有快取條目失效。query_cache_min_res_unit),LRU 淘汰,易產生碎片。| 限制 | 說明 | 影響 |
|---|---|---|
| 僅緩存 SELECT | INSERT/UPDATE/DELETE/SHOW/存儲過程/觸發器/Prepared Statement/游標均不緩存 | 寫多場景無效 |
| 完全文本匹配 | 註釋、空格、大小寫、換行差異 → 不同 Key | 命中率極低,需規範 SQL 模板 |
| 不支援子查詢/視圖/UNION 部分結果 | 只緩存最外層完整結果集 | 複雜查詢無法受益 |
| 不確定性函數失效 | NOW(), RAND(), UUID(), CONNECTION_ID(), USER() 等 | 含此類函數的查詢永不緩存 |
| 表鎖狀態下仍可讀快取 | 除非 query_cache_wlock_invalidate=ON | 可能讀到舊數據 (最終一致性) |
| Prepared Statement 不支援 | 5.7 開始支援但有條件限制 | 連接池/ORM 常用預備語句無法受益 |
| 事務隔離影響 | 快取結果可能不可重複讀 | RC/RR 隔離級下語義偏差 |
[mysqld]
query_cache_type = 1 # 0=OFF, 1=ON (默認), 2=DEMAND (需 SQL_CACHE)
query_cache_size = 64M # 總內存,0 禁用
query_cache_limit = 2M # 單查詢結果上限,超過不緩存
query_cache_min_res_unit = 4K # 分配塊大小,影響碎片率
query_cache_wlock_invalidate = OFF # 寫鎖時是否失效快取
SHOW STATUS LIKE 'Qcache%';
| 變量 | 含義 |
|---|---|
| Qcache_free_blocks | 空閒塊數 (碎片指標) |
| Qcache_free_memory | 可用內存 (位元組) |
| Qcache_hits | 命中次數 |
| Qcache_inserts | 插入快取次數 |
| Qcache_lowmem_prunes | 因內存不足淘汰次數 (關鍵壓力指標) |
| Qcache_not_cached | 未緩存查詢數 (不滿足條件/超限/函數) |
| Qcache_queries_in_cache | 當前快取條目數 |
| Qcache_total_blocks | 總塊數 |
-- 命中率
Hit Rate = Qcache_hits / (Qcache_hits + Com_select)
-- 平均快取大小
Avg Size = (query_cache_size - Qcache_free_memory) / Qcache_queries_in_cache
-- 碎片率
Frag Ratio = Qcache_free_blocks / Qcache_total_blocks -- > 0.2 需整理
-- 內存壓力
Prune Rate = Qcache_lowmem_prunes / Uptime -- 持續增長需擴容或降低 limit
query_cache_type=0)。Qcache_lowmem_prunes,逐步調整至穩定。避免 > 512M (全局鎖競爭劇增)。FLUSH QUERY CACHE 整理碎片不清空內容;RESET QUERY CACHE 清空所有快取。query_cache_type=2 + SELECT SQL_CACHE ... 精確控制哪些查詢入快取。LOCK_query_cache,高併發下嚴重退化為串行。Qcache_hits / (Qcache_hits + Com_select),若 < 10% 直接關閉無感遷移。innodb_buffer_pool_size 吸收原 QC 內存,提升物理讀效能。optimizer_switch='derived_merge=on,derived_condition_pushdown=on' 利用優化器新特性補償。Query Cache 是 MySQL 早期為單核、低併發、讀多寫少場景設計的產物。隨著多核普及、高併發常態化、InnoDB MVCC 成熟,其架構缺陷已無法通過參數調優根治。理解其機制與限制,既是對歷史系統的負責,也是技術演進的見證。