MySQL查詢快取

2021-08-14 06:31:20 字數 2094 閱讀 1386

mysql查詢快取儲存查詢返回的完整結果。當查詢命中快取,mysql會立刻返回結果,跳過了解析,優化和執行階段。

查詢快取執行過程:

1.通過乙個大小寫不敏感的檢查看看sql語句是不是以sel開頭。

2.若是以sel開頭則獲取快取資料,若是命中則直接返回結果。

3.若沒有命中,則通過sql語句查詢資料。

4.返回查詢結果給客戶端。同時存入查詢快取,但不是所有的查詢結果都會存入查詢快取,詳細見下面。

快取未命中可能的情況:

1.由於查詢語句中包含不確定的函式,或者查詢結果太大,超過query_cache_limit的值,查詢結果無法快取。

2.mysql從未處理過這個查詢,查詢結果沒有快取過。

3.之前快取了查詢結果,但是由於查詢快取記憶體不足,mysql將某些快取逐出,導致未命中。

4.快取失效操作太多。資料修改,記憶體不足,快取碎片都會導致快取失效。

5.查詢快取還沒有完成預熱,mysql還沒有機會將查詢結果都快取起來。

不會快取結果的情況:

1.當查詢語句中有一些不確定的資料時,則不會被快取。如包含函式now(),current_date()等類似的函式,或者使用者自定義的函式,儲存函式,使用者變數等都不會被快取。

2.當查詢的結果大於query_cache_limit設定的值時,結果不會被快取。

3.對於innodb引擎來說,當乙個語句在事務中修改了某個表,那麼在這個事務提交之前,所有與這個表相關的查詢都無法被快取。因此長時間執行事務,會大大降低快取命中率。

查詢快取帶來的額外消耗:

1.在查詢之前必須先檢查是否命中快取。

2.如果這個查詢可以被快取,那麼執行完成後,mysql發現查詢快取中沒有這個查詢,則會將結果存入查詢快取,這會帶來額外的系統消耗。

3.寫入或更新資料時,mysql必須將對應表的所有快取都設定失效。如果查詢快取很大或者碎片很多時,這個操作可能帶來很大的系統消耗。

查詢快取記憶體使用:

在查詢開始返回結果的時候就分配空間,而此時無法預知查詢結果有多大,所以mysql無法為每乙個查詢結果精確的分配快取空間。

當需要將查詢結果快取的時候,mysql先申請乙個資料塊儲存結果,不論結果大小,都會至少申請乙個query_cache_min_res_unit的空間,然後將結果寫入資料塊,若申請的資料塊不足以儲存結果,那麼再申請乙個資料塊,直到全部儲存完成。

當查詢完成後,如果申請的記憶體空間還有剩餘,mysql會將其釋放,並放入空閒記憶體部分,這樣是不會產生碎片。

通過下面的步驟來驗證這個問題:

設定的分配記憶體塊的最小單位為4kb。

首先執行 show status like 'qcache%'; 檢視快取使用情況。

此時可以看到qcache_free_blocks的值為1,說明有乙個空閒塊。

現在執行一條查詢語句 select * from people where id =10001,資料遠遠小於4kb,且之前沒有被快取。

然後再執行 show status like 'qcache%'; 檢視快取使用情況。

而此時還是只有乙個空閒塊,說明在沒有併發查詢的情況下,mysql會將儲存查詢結果後產生的剩餘空間釋放,不會產生碎片。

碎片如何產生:

假設查詢的結果非常小,伺服器在併發的向兩個鏈結返回結果,這是在向a和b兩個記憶體塊寫入資料,返回完結果後**剩餘的空間時,a剩餘的空間小於query_cache_min_res_unit設定的值,這樣就不能再次被查詢快取使用,從而產生了碎片,b剩餘的空間則會釋放,併入空閒記憶體部分。

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