mysql查詢快取可以跳過sql解析優化查詢等階段,直接返回快取結果給使用者,查詢快取的工作流程如下:
命中條件
快取存在乙個hash表中,通過查詢sql,查詢資料庫,客戶端協議等作為key.在判斷是否命中前,mysql不會解析sql,而是直接使用sql去查詢快取,sql任何字元上的不同,如空格,注釋,都會導致快取不命中.
如果查詢中有不確定資料,例如current_date()和now()函式,那麼查詢完畢後則不會被快取.所以,包含不確定資料的查詢是肯定不會找到可用快取的
工作流程
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查詢開始(還未得到結果)時就去申請一塊空間,所以即使你的快取資料沒有達到這個大小,也需要用這個大小的資料塊去存(這點跟linux檔案系統的block一樣).如果結果超出這個記憶體塊的大小,則需要再去申請乙個記憶體塊.當查詢完成發現申請的記憶體塊有富餘,則會將富餘的空間釋放掉,這就會造成記憶體碎片問題,見下圖
此處查詢1和查詢2之間的空白部分就是記憶體碎片,這部分空閒記憶體是有查詢1查詢完以後釋放的,假設這個空間大小小於mysql設定的記憶體塊大小,則無法再被使用,造成碎片問題
在查詢開始時申請分配記憶體block需要鎖住整個空閒記憶體區,所以分配記憶體塊是非常消耗資源的.注意這裡所說的分配記憶體是在mysql初始化時就開闢的那塊記憶體上分配的.
快取的使用時機
衡量開啟快取是否對系統有效能提公升是乙個很難的話題
1. 通過快取命中率判斷, 快取命中率 = 快取命中次數 (qcache_hits) / 查詢次數 (com_select)
2. 通過快取寫入率, 寫入率 = 快取寫入次數 (qcache_inserts) / 查詢次數 (qcache_inserts)
3. 通過 命中-寫入率 判斷, 比率 = 命中次數 (qcache_hits) / 寫入次數 (qcache_inserts), 高效能mysql中稱之為比較能反映效能提公升的指數,一般來說達到3:1則算是查詢快取有效,而最好能夠達到10:1
快取配置引數
1. query_cache_type: 是否開啟快取
可選項1) off: 關閉
2) on: 總是開啟
3) demand: 只有明確寫了sql_cache的查詢才會吸入快取
2. query_cache_size: 快取使用的總記憶體空間大小,單位是位元組,這個值必須是1024的整數倍,否則mysql實際分配可能跟這個數值不同(感覺這個應該跟檔案系統的blcok大小有關)
3. query_cache_min_res_unit: 分配記憶體塊時的最小單位大小
4. query_cache_limit: mysql能夠快取的最大結果,如果超出,則增加 qcache_not_cached的值,並刪除查詢結果
5. query_cache_wlock_invalidate: 如果某個資料表被鎖住,是否仍然從快取中返回資料,預設是off,表示仍然可以返回
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數
減少碎片策略
1. 選擇合適的block大小
2. 使用 flush query cache 命令整理碎片.這個命令在整理快取期間,會導致其他連線無法使用查詢快取
ps: 清空快取的命令式 reset query cache
查詢快取問題分析
innodb與查詢快取
innodb會對每個表設定乙個事務計數器,裡面儲存當前最大的事務id.當乙個事務提交時,innodb會使用mvcc中系統事務id最大的事務id跟新當前表的計數器.
只有比這個最大id大的事務能使用查詢快取,其他比這個id小的事務則不能使用查詢快取.
另外,在innodb中,所有有加鎖操作的事務都不使用任何查詢快取
mysql資料快取查詢 Mysql查詢快取
查詢快取 mysql提供了一種快取型別,會快取整個select查詢結果。mysql查詢快取儲存查詢返回的完整結果。當查詢命中該快取,mysql會立即返回結果,跳過了解析 優化和執行階段。以下兩種情況不能被快取 頻繁更新 修改的的表,所有快取資料都會失效,mysql查詢快取會跟蹤查詢中涉及的表,如果這...
mysql 查詢快取
show variables like cache my.cnf設定 mysql慢日誌 mysql有乙個功能就是可以log下來執行的比較慢的sql語句,預設是沒有這個log的,為了開啟這個功能,要修改my.cnf或者在mysql啟動的時候加入一些引數。如果在my.cnf裡面修改,需增加如下幾行 lo...
mysql查詢快取
查詢快取不開啟 r mysql query select username from user where signup date curdate 開啟查詢快取 today date y m d r mysql query select username from user where signup...