Query Cache 直接緩存 SELECT 結果集與 SQL 文本,命中時繞過解析、優化、執行,極大提升讀取效能。但它有全局鎖、碎片、失效機制等副作用,濫用反拖垮效能。本文從五個維度系統梳理。
SELECT/預處理查詢(5.1.17+)的結果集 + SQL 文本SQL_NO_CACHE、不確定函數 (NOW(), RAND(), UUID() 等)mysql, information_schema)、臨時表、SELECT ... INTOSERIALIZABLE、含 LOCK IN SHARE MODE/FOR UPDATE| 參數 | 建議值 | 說明 |
|---|---|---|
| query_cache_type | 2 (DEMAND) | 0=關閉, 1=全開, 2=按需(SQL_CACHE) |
| query_cache_size | 64M~128M | 非越大越好,超過 128M 往往得不償失 |
| query_cache_limit | 1M (預設) | 單個結果集上限,防大查詢佔滿;建議 16K~1M |
| query_cache_min_res_unit | 4K (預設) | 分配最小塊,太大產生碎片,太小增加分配開銷;建議 1K~16K |
| query_cache_wlock_invalidate | 0 (預設) | MyISAM 寫鎖時是否仍允許讀緩存;InnoDB 無影響 |
FLUSH QUERY CACHE:整理碎片(不清空資料)RESET QUERY CACHE / FLUSH TABLES:完全清空緩存區碎片率 = Qcache_free_blocks / Qcache_total_blocks * 100%
命中率 = (Qcache_hits - Qcache_inserts) / Qcache_hits * 100%
記憶體使用率 = (query_cache_size - Qcache_free_memory) / query_cache_size * 100%
低記憶體修剪次數 = Qcache_lowmem_prunes (LRU 淘汰計數)
Qcache_lowmem_prunes 持續增長 → 擴大 query_cache_sizeQcache_lowmem_prunes 平穩 → 縮小或關閉,業務重複查詢少freeing items 狀態頻繁 → 鎖競爭嚴重,考慮關閉query_cache_min_res_unit ≈ (query_cache_size - Qcache_free_memory) / Qcache_queries_in_cache
query_cache_type=2 + SQL_CACHE 精準控制MySQL 5.7 開始棄用 Query Cache,8.0 **完全移除**。新架構請改用 Redis、ProxySQL、應用層緩存等方案。
正確認知 Query Cache,才能在舊版本維護期內榨乾其價值,並在遷移時平滑過渡。