核心機制:SQL 文本精確匹配鍵值
- 僅缓存
SELECT 語句(以 SELECT 開頭)。
- Key = 完整 SQL 文本(發送給 Server 前的原始字符串)。
- 大小寫敏感、空格敏感、註釋敏感:
SELECT 1、select 1、SELECT /*c*/1 是三個不同 Key。
- 客戶端預處理差異:官方
mysql 客戶端會去除註釋、首尾空白;PHP mysql 擴展**不處理**,直接發送原文。
失效策略:表級粒度,無增量更新
- 任意表發生
INSERT/UPDATE/DELETE/TRUNCATE/ALTER,**該表相關的所有 Query Cache 條目全部失效**。
- 頻繁寫入的表**不適合開啟 QC**,失效開銷超過命中收益。
- 手動控制:
SELECT SQL_NO_CACHE ... 禁用;SELECT SQL_CACHE ... 顯式啟用(需 query_cache_type=2)。
內存塊管理
- 結果集分塊存儲,塊大小由
query_cache_min_res_unit 控制(默認 4KB)。
- 最後一塊未滿自動釋放碎片。
- 每個缓存條目佔用:1 個 SQL 文本塊 + N 個結果塊 + 1 個表信息塊(多表共享)。
- 總塊數 ≈
Qcache_queries_in_cache * 2 + 涉及表數。
關鍵配置參數
| 參數 | 說明 | 建議 |
query_cache_type | 0=關閉 1=開啟(可用 SQL_NO_CACHE 禁用) 2=按需(需 SQL_CACHE) | 生產建議 1,熱點表加 SQL_NO_CACHE |
query_cache_size | 分配給 QC 總內存(<40KB 實際關閉,按 1KB 對齊) | 根據命中率調整,典型 64M-256M |
query_cache_limit | 單個查詢結果超過此值不缓存(默認 1MB) | 避免大結果集佔滿池 |
query_cache_min_res_unit | 單次分配塊大小(默認 4KB) | 見下文調優 |
狀態變量與調優決策
SHOW STATUS LIKE 'Qcache%';
| 變量 | 含義 | 調優動作 |
Qcache_hits | 命中次數 | 核心指標,持續增長即有效 |
Qcache_inserts | 新增缓存數 | 與 hits 比算命中率 |
Qcache_lowmem_prunes | 因內存不足被剔除數 | 快速增長 → 增大 query_cache_size |
Qcache_free_memory | 剩餘內存 | 過小 → 擴容 |
Qcache_free_blocks | 空閒碎片塊數 | 過多 → FLUSH QUERY CACHE 整理 |
Qcache_total_blocks | 總塊數 | 配合 queries_in_cache 算平均塊數 |
query_cache_min_res_unit 調優公式
- 平均塊數 =
Qcache_total_blocks / Qcache_queries_in_cache。接近 2 → 塊大小合適。
- 若總塊數遠大於 2×查詢數 → **增大**
query_cache_min_res_unit(減少分配次數)。
- 若
Qcache_queries_in_cache * query_cache_min_res_unit 遠大於 query_cache_size - Qcache_free_memory → **減小** 塊大小(減少碎片浪費)。
⚠️ 重要提示
MySQL 5.7.20 **棄用**,MySQL 8.0 **完全移除** Query Cache。原因:鎖爭用嚴重、無法利用多核、InnoDB 事務隔離級難以兼容。新架構請轉用 Redis/Memcached 等外部分布式緩存。