MySQL 4.0+ 引入,將 SELECT 查詢文本 (經正規化) 與結果集 以 Key-Value 形式存入記憶體。後續完全相同的查詢 (含大小寫、空格、註解) 直接返回快取結果,繞過解析、優化、執行、存儲引擎層。
關鍵限制:
SQL_NO_CACHE、CURRENT_DATE()/NOW()/RAND() 等非確定性函數query_cache_limit 不快取| 場景特徵 | QC 效果 | 建議 |
|---|---|---|
| 讀多寫少 (95%+ SELECT)、重複查詢率高、資料變更頻率低 | 極佳,命中率 80%+ | 開啟,適度分配記憶體 |
| 寫入頻繁、表較小、查詢模式多變 | 負效能 (失效開銷 > 命中收益) | 關閉 (query_cache_type=0, query_cache_size=0) |
| 大結果集、Blob/Text 多 | 記憶體壓力大、碎片嚴重 | 關閉或極小限額 |
| 8.0+ 環境 | 不存在 | 遷移至 ProxySQL Query Cache / Redis / 應用層 |
[mysqld]
# 總記憶體上限,0=關閉。建議 64M-512M,不可過大 (鎖爭用)
query_cache_size = 128M
# 單個查詢結果上限,超過不快取。預設 1M,建議 64K-1M
query_cache_limit = 256K
# 分配最小記憶體塊,預設 4K。碎片多時調大 (16K-64K),小結果集調小
query_cache_min_res_unit = 16K
# 快取類型:0=關閉、1=開啟 (預設)、2=按需 (需 SQL_CACHE 提示)
query_cache_type = 1
# 寫入時是否讓快取失效前等待鎖,ON=更安全但有延遲
query_cache_wlock_invalidate = OFF
| 變量 | 含義 | 健康判讀 |
|---|---|---|
Qcache_free_memory | 剩餘可用記憶體 | 接近 0 → 擴容或關閉 |
Qcache_hits | 命中次數 | 核心效益指標 |
Qcache_inserts | 新增快取條目數 | 寫入頻率 |
Qcache_lowmem_prunes | 因記憶體不足被淘汰數 | 持續增長 → 記憶體不足,需擴容或關閉 |
Qcache_not_cached | 未快取查詢數 (非確定性/超大/關閉) | 參考 |
Qcache_queries_in_cache | 當前快取查詢數 | 容量利用率 |
Qcache_total_blocks | 總記憶體塊數 (含碎片) | 基線 |
Qcache_free_blocks | 空閒記憶體塊數 | 遠大於 1 → 嚴重碎片化,需 FLUSH QUERY CACHE |
成因:MySQL 採用動態記憶體分配,每次分配 query_cache_min_res_unit 大小塊。結果集較小時,塊尾部空間成為碎片;釋放時若相鄰塊也空閒會合併,否則形成碎片。
現象:Qcache_free_blocks 大、Qcache_free_memory 看似充足但無法分配新查詢、Qcache_lowmem_prunes 飆升。
整理:
FLUSH QUERY CACHE; -- 僅整理碎片,不清除內容,Qcache_free_blocks 變 1
RESET QUERY CACHE; -- 完全清空快取,慎用
建議:低峰期定時任務每小時執行一次 FLUSH QUERY CACHE。
query_cache_min_res_unit = (query_cache_size - Qcache_free_memory) / Qcache_queries_in_cache
意義:平均每個快取查詢佔用的記憶體。實測調整後可減少 30-50% 碎片塊。
-- 強制不快取 (query_cache_type=1 時)
SELECT SQL_NO_CACHE * FROM large_table WHERE ...;
-- 強制快取 (query_cache_type=2 時)
SELECT SQL_CACHE * FROM hot_table WHERE ...;
-- 關閉會話級快取
SET SESSION query_cache_type = OFF;
| 方案 | 定位 | 優點 | 缺點 |
|---|---|---|---|
| ProxySQL Query Cache | 中間件層 | 透明無侵入、支援多 MySQL、LRU 淘汰、統計豐富 | 額外元件、單點需 HA |
| Redis / Memcached | 應用層 / Sidecar | 高效能、分散式、資料結構豐富、TTL 精確控制 | 應用需改造、快取一致性自管 |
| 應用程式本地快取 (Caffeine/Guava) | 進程內 | 零網路延遲、極高 QPS | 多實例不一致、重啟失效、記憶體受限 |
| Materialized View / Summary Table | 資料庫層 | 資料一致性強、查詢極快 | 維護成本高、非即時 |
建議:熱點查詢 → ProxySQL QC;複雜聚合 → Summary Table + 定時刷新;Session 級熱點 → 本地快取;分散式服務共享 → Redis。