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

MySQL Query Cache 核心機制與運維實戰

     編輯:MySQL 資料庫相關知識

MySQL 內建 Query Cache 將「完全相同的 SELECT 文本」與結果集綁定緩存,命中時繞過解析、優化、執行直接返回。但其大小寫敏感、含非確定性函數不緩存、失效機制激進 等特性導致高併發寫入場景下反成累贅。本文梳理核心參數、啟用判斷、監控指標、最佳實踐。

核心參數速查

參數作用典型值/建議
have_query_cache是否編譯支援(只讀)YES/NO
query_cache_type啟用模式OFF(0)/ON(1)/DEMAND(2)
query_cache_size緩存總內存(0=禁用)64MB-512MB,**勿超 1GB**(鎖競爭劇增)
query_cache_limit單個結果集最大緩存1MB-4MB,防大結果集佔滿
query_cache_min_res_unit分配最小塊(影響碎片)4KB-8KB

關鍵行為鐵律

  1. 文本完全匹配:SELECT * FROM t ≠ select * from t ≠ SELECT * FROM t (尾隨空格)。應用層必須統一 SQL 格式化。
  2. 非確定性函數不緩存:NOW()、RAND()、UUID()、CURRENT_DATE 等導致不緩存。
  3. 寫入即失效:表任意 INSERT/UPDATE/DELETE/TRUNCATE 觸發該表所有緩存條目失效,**鎖住 query_cache_lock**,高寫入場景成熱點。
  4. 權限檢查:緩存存儲時綁定用戶權限,不同權限用戶無法共用緩存。

啟用決策樹

IF (讀寫比 > 10:1) AND (表數據相對靜態) AND (SQL 文本高度可復用)
   THEN 啟用 query_cache_type=DEMAND, 關鍵查詢用 SQL_CACHE
ELSE IF (寫入頻繁 OR 表數據高度動態 OR SQL 參數化差)
   THEN 關閉 query_cache_type=OFF, query_cache_size=0
ELSE 保持關閉,觀察 Qcache_hit_rate 指標再決策

監控指標與健康度判斷

SHOW STATUS LIKE 'Qcache%';
-- 關鍵指標:
Qcache_hits / (Qcache_hits + Qcache_inserts + Qcache_not_cached)  -- 命中率
Qcache_lowmem_prunes  -- 因內存不足淘汰次數(持續增長 = 容量不足或碎片嚴重)
Qcache_free_blocks / Qcache_total_blocks  -- 碎片率(> 0.3 需 FLUSH QUERY CACHE)
Qcache_queries_in_cache  -- 當前緩存條目數

運維操作

  • FLUSH QUERY CACHE:整理碎片,**不清空內容**。
  • RESET QUERY CACHE / FLUSH TABLES:**清空所有緩存**。
  • SELECT SQL_CACHE ... / SELECT SQL_NO_CACHE ...:DEMAND 模式下顯式控制單條語句緩存行為。

最佳實踐總結

  1. 默認關閉(query_cache_type=OFF, query_cache_size=0),MySQL 8.0 已移除該功能。
  2. 僅在「極高讀寫比、靜態數據、固定 SQL 模板」的報表/配置表場景啟用 DEMAND 模式。
  3. 應用層統一 SQL 大小寫、格式化,使用準備語句(PreparedStatement)天然保證文本一致。
  4. 定期 FLUSH QUERY CACHE 整理碎片,監控 Qcache_lowmem_prunes 趨勢。
  5. 大結果集查詢強制 SQL_NO_CACHE,避免污染緩存池。

總結

Query Cache 是把雙刃劍:命中即極速,失效即開銷。MySQL 5.7 仍保留但已棄用,8.0 徹底移除。現代架構應轉向應用層緩存,利用 Redis/Memcached 實現業務感知的緩存策略(TTL、主動失效、標籤分組),而非依賴數據庫層面的粗暴文本匹配。

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