首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 查詢緩存 從入門到精通:啟用、配置、驗證與避坑全攻略

     編輯:MySQL 資料庫相關知識

前言:被誤解的「加速器」

MySQL Query Cache 自 4.0 版本引入,旨在將完全相同的 SELECT 結果集緩存於記憶體,下次相同查詢直接返回,繞過解析、優化、執行全流程。然而,預設關閉、配置陷阱多、高併發寫入場景反成累贅,導致許多 DBA 望而卻步。本文將系統梳理啟用流程、關鍵參數、驗證方法與適用邊界,助您精準決策「用還是不用」。

一、核心誤區:have_query_cache=YES ≠ 已啟用

執行 SHOW VARIABLES LIKE '%query_cache%' 時,have_query_cache 僅表示**當前版本支援**該功能,**真正開關**取決於:

  • query_cache_size > 0(預設為 0,即禁用)
  • query_cache_type = 1 (ON) 或 2 (DEMAND)

二、標準啟用配置

[mysqld]
query_cache_size = 128M          # 建議 1024 倍數,視查詢結果集大小調整
query_cache_type = 1             # 1=緩存所有 SELECT;2=僅緩存 SQL_CACHE 指定查詢
query_cache_limit = 2M           # 單個查詢結果超過此值不緩存
query_cache_min_res_unit = 2K    # 緩存塊最小單位,減少碎片(小結果集場景可調小)

重啟生效:修改配置後需 systemctl restart mysqld。

三、query_cache_type 三種模式詳解

值別名行為適用場景
0OFF禁用緩存,不分配記憶體高寫入、低重複查詢系統
1ON緩存所有 SELECT,除非 SQL_NO_CACHE讀多寫少、高重複查詢業務
2DEMAND僅緩存 SQL_CACHE 指定的 SELECT精細控制,混合負載系統

注意:query_cache_type 僅接受數字 0/1/2,不可寫 ON/OFF。

四、驗證緩存是否真正生效

1. 確認變量生效


mysql> SHOW VARIABLES LIKE '%query_cache%';
+-------------------------+-----------+
| Variable_name           | Value     |
+-------------------------+-----------+
| have_query_cache        | YES       |
| query_cache_limit       | 1048576   |
| query_cache_min_res_unit| 4096      |
| query_cache_size        | 134217728 |  # 128M = 128*1024*1024
| query_cache_type        | ON        |
| query_cache_wlock_invalidate | OFF  |
+-------------------------+-----------+

2. 實戰測試:觀察狀態變量變化


-- 1. 基線快照
mysql> SHOW STATUS LIKE 'Qcache%';
+-------------------------+-----------+
| Variable_name           | Value     |
+-------------------------+-----------+
| Qcache_free_blocks      | 1         |
| Qcache_free_memory      | 134208800 |
| Qcache_hits             | 0         |
| Qcache_inserts          | 0         |
| Qcache_lowmem_prunes    | 0         |
| Qcache_not_cached       | 2         |
| Qcache_queries_in_cache | 0         |
| Qcache_total_blocks     | 1         |
+-------------------------+-----------+

-- 2. 首次執行查詢(未命中 -> 插入緩存)
mysql> SELECT * FROM user WHERE id = 2;
mysql> SHOW STATUS LIKE 'Qcache%';
-- 觀察:Qcache_inserts=1, Qcache_hits=0, Qcache_queries_in_cache=1

-- 3. 再次執行相同查詢(命中)
mysql> SELECT * FROM user WHERE id = 2;
mysql> SHOW STATUS LIKE 'Qcache%';
-- 觀察:Qcache_hits=1, Qcache_inserts=1 (不變),驗證緩存生效!

五、關鍵狀態變量深度解讀

變量含義健康判讀
Qcache_free_memory剩餘可用記憶體過大說明分配過剩;接近 0 需擴容或清理碎片
Qcache_hits命中次數核心效能指標,越高越好
Qcache_inserts未命中插入次數過高說明重複查詢少或緩存失效頻繁
Qcache_lowmem_prunes因記憶體不足被剔除的查詢數> 0 持續增長,需增大 query_cache_size
Qcache_free_blocks空閒塊數量過大(> 總塊 20%)表明碎片嚴重,執行 FLUSH QUERY CACHE 整理
Qcache_not_cached因 query_cache_type 策略未緩存的查詢數輔助判斷策略是否合理
Qcache_queries_in_cache當前緩存查詢條數配合 Qcache_total_blocks 估算平均塊大小

核心健康度公式

  • 命中率 = Qcache_hits / (Qcache_hits + Qcache_inserts) × 100% —— **目標 > 80%**
  • 碎片率 = Qcache_free_blocks / Qcache_total_blocks × 100% —— **目標 < 20%**
  • 利用率 = (query_cache_size - Qcache_free_memory) / query_cache_size × 100% —— **25%~80% 為健康區間**

六、避坑指南:何時應「果斷關閉」

  • 寫入頻繁、表變更高:每次 DML 導致相關表所有緩存失效,鎖競爭劇增,寫入延遲飆升。
  • 查詢差異大、無重複:Qcache_not_cached 高企,緩存利用率極低,純增開銷。
  • 大結果集查詢:單次結果超 query_cache_limit 不緩存,佔用緩存管理結構卻無產出。
  • 高併發場景:全局鎖保護緩存元數據,嚴重限制擴展性(MySQL 8.0 已移除 Query Cache)。

一鍵禁用:SET GLOBAL query_cache_size = 0; SET GLOBAL query_cache_type = 0;(運行時生效,重啟需改配置)。

七、運維小貼士

  1. 定期整理碎片:FLUSH QUERY CACHE(不清空內容)或 RESET QUERY CACHE(清空)。
  2. 監控告警:Qcache_lowmem_prunes 連續 5 分鐘 > 100/分 觸發擴容告警。
  3. 版本規劃:MySQL 5.7 已標記棄用,8.0 完全移除。新架構建議改用 Redis、ProxySQL 等外部緩存層。

結語

Query Cache 是把「雙刃劍」:用對場景(靜態數據、高重複讀)、配對參數(Size/Type/Limit/Min_Unit)、建對監控(Hit/Prune/Fragment),才能真正化身加速器。對於現代高併發、頻寫業務,**大膽關閉、外部緩存**往往是更優選擇。願本文助您在「開與關」間,做出最理性的技術決策。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved