mysql 緩存機制

1. MySQL緩存簡介

1. MySQL緩存機制說明

MySQL緩存機制即緩存sql 文本及緩存結果,用KV形式保存再服務器內存中,若是運行相同的sql,服務器直接從緩存中去獲取結果,不須要再去解析、優化、執行sqlmysql

2. MySQL緩存失效

  • 在表的結構或數據發生改變時,查詢緩存中的數據再也不有效,查詢緩存值的相關條目將被清空
  • INSERT、UPDATE、 DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE會致使緩存數據失效

3. 使用場景

  • 對於頻繁更新的表,查詢緩存不合適
  • 對於一些不變的數據且有大量相同sql查詢的表,查詢緩存能夠大大提升查詢的性能

2. 命中條件

  • 緩存的數據結構是hash表
  • 以SQL、數據庫名和客戶端協議等做爲KEY
  • 在判斷命中前,MySQL不會解析SQL,而是使用SQL去查詢緩存,SQL上的任何字符的不一樣,如空格、註釋等都會致使緩存不命中
  • 若是查詢有不肯定的數據,如like now()、current_date(),那麼查詢完成後結果都不會被緩存

3. 工做流程

  1. 服務器接收SQL,以SQL和一些其餘條件爲key查找緩存表
  2. 若是緩存命中,則直接返回緩存
  3. 若是緩存沒有命中,則執行SQL查詢,包括SQL解析、優化等。
  4. 執行完SQL查詢結果之後,將SQL查詢結果寫入緩存表

4. 緩存失敗

  • 當某個表正在寫入數據,則這個表的緩存將會處於失效狀態
  • 在InnoDB中,若是某個事務修改了表,則這個表的緩存在事務提交前都會處於失效狀態,即在事務提交前,這個表的相關查詢都沒法被緩存

5. 緩存的內存管理

  • MySQL緩存機制會在內存中開闢一塊內存(query_cache_size)區來維護緩存數據,其中大概有40K的空間是用來維護緩存數據的元數據的,例如空間內存、數據表和查詢結果的映射,SQL和查詢結果的映射。
  • MySQL緩存機制將大內存塊分爲小內存塊(query_cache_min_res_unit),每一個小塊中存儲自身的類型、大小和查詢結果數據,還有先後內存塊的指針。
  • MySQL緩存機制會在SQL查詢開始(還未獲得結果)時就去申請一塊內存空間,因此即便緩存數據沒有達到這個大小也須要佔用申請的內存塊空間(like linux filesystem’s block)。若是超出申請內存塊的大小,則須要再申請一個內存塊。當查詢完成發現申請的內存有富餘,則會將富餘的內存空間釋放掉,於是可能會形成內存碎片。

MySQL緩存管理

6. 緩存的使用時機

1. 經過緩存命中率判斷

緩存命中率 = 緩存命中次數 (Qcache_hits) / 查詢次數 (Com_select)linux

2. 經過緩存寫入率判斷

寫入率 = 緩存寫入次數 (Qcache_inserts) / 查詢次數 (Qcache_inserts)sql

3. 經過命中-寫入率判斷

比率 = 命中次數 (Qcache_hits) / 寫入次數 (Qcache_inserts),數據庫

高性能MySQL中稱之爲比較能反映性能提高的指數,通常來講達到3:1則算是查詢緩存有效,而最好可以達到10:1緩存

7. 緩存參數配置

1. 查看緩存相關配置

SHOW VARIABLES LIKE '%query_cache%';服務器

2. query_cache_type

  • 是否打開緩存,可選參數有:
    • OFF(0):關閉 ,不使用查詢緩存
    • ON(1):老是打開 ,始終使用查詢緩存
    • DEMAND(2):按需使用查詢緩存,只有明確寫了SQL_CACHE的查詢纔會寫入緩存
  • 若是query_cache_type爲1而又不想利用查詢緩存中的數據,能夠用下面的SQL:
    • SELECT SQL_NO_CACHE * FROM my_table WHERE condition;
  • 若是值爲2,要使用緩存的話,須要使用SQL_CACHE開關參數:
    • SELECT SQL_CACHE * FROM my_table WHERE condition;

3. query_cache_size

  • 緩存使用的總內存空間大小,單位是字節,這個值必須是1024的整數倍;不然MySQL實際分配可能跟這個數值不一樣(感受這個應該跟文件系統的blcok大小有關)
  • 默認狀況下query_cache_size爲0,表示爲查詢緩存預留的內存爲0,則沒法使用查詢緩存
  • 設置query_cache_size的值
    • SET GLOBAL query_cache_size = 134217728; -- 注意值若是設得過小不會生效

4. query_cache_min_res_unit

分配內存塊時的最小單位大小數據結構

5. query_cache_limit

MySQL可以緩存的最大結果,若是超出,則增長 Qcache_not_cached的值,並刪除查詢結果函數

6. query_cache_wlock_invalidate

若是某個數據表被鎖住,是否仍然從緩存中返回數據,默認是OFF,表示仍然能夠返回性能

7. GLOBAL STATUS 中關於緩存的參數解釋

  1. Qcache_free_blocks:緩存池中空閒塊的個數
  2. Qcache_free_memory:緩存中空閒內存量
  3. Qcache_hits:緩存命中次數
  4. Qcache_inserts:緩存寫入次數
  5. Qcache_lowmen_prunes:因內存不足刪除緩存次數
  6. Qcache_not_cached:查詢未被緩存次數,例如查詢結果超出緩存塊大小,查詢中包含可變函數等
  7. Qcache_queries_in_cache:當前緩存中緩存的SQL數量
  8. Qcache_total_blocks:緩存總block數

8. 減小緩存碎片策略

  1. 選擇合適的block大小
  2. 使用 FLUSH QUERY CACHE 命令整理碎片,這個命令在整理緩存期間,會致使其餘鏈接沒法使用查詢緩存

清空緩存的命令

RESET QUERY CACHE; // 從查詢緩存中移出全部查詢。
FLUSH TABLES; //關閉全部打開的表,同時該操做將會清空查詢緩存中的內容。

MySQL緩存配置

9. InnoDB查詢緩存

    1. InnoDB存儲引擎會對每一個表設置一個事務計數器,裏面存儲當前最大的事務ID
    2. 當一個事務提交時,InnoDB會使用MVCC中系統最大的事務ID更新當前表的計數器
    3. 只有比這個最大ID大的事務能使用查詢緩存,其餘比這個ID小的事務則不能使用查詢緩存
    4. 在InnoDB中,全部加鎖操做的事務都不使用任何查詢緩存
    5. 查詢必須是徹底相同的(逐字節相同)纔可以被認爲是相同的。
    6. 查詢字符串因爲其它緣由使用不一樣的數據庫、不一樣的協議版本或者不一樣的默認字符集都會被認爲是不一樣的查詢而分別進行緩存。
相關文章
相關標籤/搜索