mysql 缓存机制
mysql緩存機制就是緩存sql 文本及緩存結果,用KV形式保存再服務器內存中,如果運行相同的sql,服務器直接從緩存中去獲取結果,不需要在再去解析、優化、執行sql。 如果這個表修改了,那么使用這個表中的所有緩存將不再有效,查詢緩存值得相關條目將被清空。表中得任何改變是值表中任何數據或者是結構的改變,包括insert,update,delete,truncate,alter table,drop table或者是drop database 包括那些映射到改變了的表的使用merge表的查詢,顯然,者對于頻繁更新的表,查詢緩存不合適,對于一些不變的數據且有大量相同sql查詢的表,查詢緩存會節省很大的性能。
命中條件
緩存存在一個hash表中,通過查詢SQL,查詢數據庫,客戶端協議等作為key,在判斷命中前,mysql不會解析SQL,而是使用SQL去查詢緩存,SQL上的任何字符的不同,如空格,注釋,都會導致緩存不命中。如果查詢有不確定的數據like now(),current_date(),那么查詢完成后結果者不會被緩存,包含不確定的數的是不會放置到緩存中。
工作流程
1.服務器接收SQL,以SQL和一些其他條件為key查找緩存表
2.如果找到了緩存,則直接返回緩存
3.如果沒有找到緩存,則執行SQL查詢,包括原來的SQL解析,優化等。
4.執行完SQL查詢結果以后,將SQL查詢結果緩存入緩存表
緩存失敗
當某個表正在寫入數據,則這個表的緩存(命中緩存,緩存寫入等)將會處于失效狀態,在Innodb中,如果某個事務修改了這張表,則這個表的緩存在事務提交前都會處于失效狀態,在這個事務提交前,這個表的相關查詢都無法被緩存。
緩存的內存管理
緩存會在內存中開辟一塊內存(query_cache_size)來維護緩存數據,其中大概有40K的空間是用來維護緩存數據的元數據的,例如空間內存,例如空間內存,數據表和查詢結果映射,SQL和查詢結果映射的。
mysql將這個大內存塊分為小內存塊(query_cache_min_res_unit),每個小塊中存儲自身的類型、大小和查詢結果數據,還有前后內存塊的指針。
mysql需要設置單個小存儲塊大小,在SQL查詢開始(還未得到結果)時就去申請一塊內存空間,所以即使你的緩存數據沒有達到這個大小也需要這個大小的數據塊去保存(like linux filesystem’s block)。如果超出這個內存塊的大小,則需要再申請一個內存塊。當查詢完成發現申請的內存有富余,則會將富余的內存空間是放點,這就會造成內存碎片的問題,見下圖:
緩存的使用時機
衡量打開緩存是否對系統有性能提升是一個很難的話題
緩存參數配置
可選項
1) OFF: 關閉
2) ON: 總是打開
3) DEMAND: 只有明確寫了SQL_CACHE的查詢才會吸入緩存
GLOBAL STAUS 中 關于 緩存的參數解釋:
Qcache_free_blocks: 緩存池中空閑塊的個數
Qcache_free_memory: 緩存中空閑內存量
Qcache_hits: 緩存命中次數
Qcache_inserts: 緩存寫入次數
Qcache_lowmen_prunes: 因內存不足刪除緩存次數
Qcache_not_cached: 查詢未被緩存次數,例如查詢結果超出緩存塊大小,查詢中包含可變函數等
Qcache_queries_in_cache: 當前緩存中緩存的SQL數量
Qcache_total_blocks: 緩存總block數
減少碎片策略
PS: 清空緩存的命令式 RESET QUERY CACHE
InnoDB與查詢緩存
Innodb會對每個表設置一個事務計數器,里面存儲當前最大的事務ID.當一個事務提交時,InnoDB會使用MVCC中系統事務ID最大的事務ID跟新當前表的計數器.
只有比這個最大ID大的事務能使用查詢緩存,其他比這個ID小的事務則不能使用查詢緩存.
另外,在InnoDB中,所有有加鎖操作的事務都不使用任何查詢緩存
查詢必須是完全相同的(逐字節相同)才能夠被認為是相同的。另外,同樣的查詢字符串由于其它原因可能認為是不同的。使用不同的數據庫、不同的協議版本或者不同 默認字符集的查詢被認為是不同的查詢并且分別進行緩存。
總結
以上是生活随笔為你收集整理的mysql 缓存机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql 如何清除sql缓存
- 下一篇: mysql标准规范