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

MySQL 查詢緩存與覆蓋索引深度解析:SQL_NO_CACHE 真相與最佳實踐

     編輯:MySQL 資料庫相關知識

一、SQL_NO_CACHE 迷思揭秘

官方文檔定義:SQL_NO_CACHE means that the query result is not cached. It does not mean that the cache is not used to answer the query.

翻譯: 該查詢**結果不寫入** Query Cache,**但不代表本次查詢不讀取 Cache**。

若要強制不讀取 Cache,需:RESET QUERY CACHE 或修改表結構導致 Cache 失效。

二、Query Cache 參數詳解

參數含義建議值
have_query_cache是否支援 Query CacheYES(5.7 預設開啟,8.0 已移除)
query_cache_size快取總記憶體大小,0 為停用0(高併發寫入場景建議關閉)
query_cache_type快取模式:0=OFF, 1=ON, 2=DEMAND0 或 2
query_cache_limit單次查詢結果最大可快取大小1M(預設)
query_cache_min_res_unit快取分配最小記憶體塊4K(預設),大結果集可調大減少碎片

三、Query Cache 狀態監控指標

SHOW STATUS LIKE 'Qcache%';
指標含義異常判斷
Qcache_hits命中次數低命中率 → 關閉或調整
Qcache_inserts寫入快取次數過高 → 寫入開銷大
Qcache_lowmem_prunes因記憶體不足被清除次數持續增長 → 擴大 query_cache_size
Qcache_free_blocks空閒記憶體塊數過多 → 碎片嚴重,執行 FLUSH QUERY CACHE
Qcache_not_cached未快取查詢數含 SQL_NO_CACHE、大結果集等

四、碎片整理與調優公式

-- 整理碎片(不清除內容)
FLUSH QUERY CACHE;

-- 完全清除
RESET QUERY CACHE;

query_cache_min_res_unit 調優公式:

query_cache_min_res_unit = (query_cache_size - Qcache_free_memory) / Qcache_queries_in_cache

五、覆蓋索引擴展案例

案例 1:sakila.inventory 組合索引

INDEX idx_store_film (store_id, film_id)
SELECT store_id, film_id FROM inventory; -- Using index

案例 2:分頁深度優化

-- 原始:LIMIT 10000, 10 掃描 10010 行
SELECT id, title, content FROM article ORDER BY created DESC LIMIT 10000, 10;

-- 優化:子查詢只取 ID(覆蓋索引),再 JOIN 回表
SELECT a.id, a.title, a.content
FROM article a
INNER JOIN (
  SELECT id FROM article ORDER BY created DESC LIMIT 10000, 10
) p USING (id);

建立索引 (created, id)(InnoDB 輔助索引含主鍵),子查詢走覆蓋索引,極速定位 ID。

六、版本演進提醒

  • MySQL 5.7:Query Cache 仍存在,但高併發下鎖爭用嚴重,**建議關閉**
  • MySQL 8.0:**完全移除 Query Cache**,官方推薦使用 Redis 等外部快取
  • 覆蓋索引在所有版本均有效,是永恆的優化手段
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved