MySQL 查詢快取

2021-09-06 11:23:43 字數 2909 閱讀 3389

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...