MySQL Query Cache(5.7.20 棄用、8.0 移除)在舊版本仍廣泛使用。本文完整解析 Qcache_* 狀態變數、碎片率/利用率/命中率三大核心比率計算與優化策略。
mysql> SHOW GLOBAL STATUS LIKE 'qcache%';
+-------------------------+-----------+
| Variable_name | Value |
+-------------------------+-----------+
| Qcache_free_blocks | 22756 |
| Qcache_free_memory | 76764704 |
| Qcache_hits | 213028692 |
| Qcache_inserts | 208894227 |
| Qcache_lowmem_prunes | 4010916 |
| Qcache_not_cached | 13385031 |
| Qcache_queries_in_cache | 43560 |
| Qcache_total_blocks | 111212 |
+-------------------------+-----------+
| 變數 | 含義 |
|---|---|
Qcache_free_blocks | 快取中相鄰空閒記憶體區塊數,過多表示碎片化 |
Qcache_free_memory | 快取剩餘可用記憶體 |
Qcache_hits | 查詢命中快取次數 |
Qcache_inserts | 新查詢寫入快取次數 |
Qcache_lowmem_prunes | 因記憶體不足清理舊查詢次數,持續增長 = 容量不足或碎片嚴重 |
Qcache_not_cached | 不適合快取的查詢數(非 SELECT、含 NOW() 等不確定函數) |
Qcache_queries_in_cache | 目前快取查詢數量 |
Qcache_total_blocks | 快取總區塊數 |
mysql> SHOW VARIABLES LIKE 'query_cache%';
+------------------------------+-----------+
| Variable_name | Value |
+------------------------------+-----------+
| query_cache_limit | 2097152 | -- 2MB,超過不快取
| query_cache_min_res_unit | 4096 | -- 4KB,最小區塊
| query_cache_size | 203423744 | -- 194MB,快取總大小
| query_cache_type | ON | -- 快取模式
| query_cache_wlock_invalidate | OFF | -- 寫鎖時是否失效快取
+------------------------------+-----------+
碎片率 = Qcache_free_blocks / Qcache_total_blocks * 100%
案例:22,756 / 111,212 ≈ 20.46% → 超過 20% 需整理。
FLUSH QUERY CACHE 整理碎片。query_cache_min_res_unit(如 2048)。利用率 = (query_cache_size - Qcache_free_memory) / query_cache_size * 100%
案例:(203,423,744 - 76,764,704) / 203,423,744 ≈ 62.26% → 健康區間。
| 利用率 | 判讀 |
|---|---|
| < 25% | 過大,建議縮小 |
| 25% - 80% | 正常 |
| > 80% 且 Qcache_lowmem_prunes > 50 | 過小或碎片嚴重 |
命中率 = (Qcache_hits - Qcache_inserts) / Qcache_hits * 100%
案例:(213,028,692 - 208,894,227) / 213,028,692 ≈ 1.94% → 極低。
query_cache_type = DEMAND,配合 SQL_CACHE 明確指定快取查詢。FLUSH QUERY CACHE 並監控三大比率。