MysQL的Query Cache原理分析

2022-09-05 21:51:15 字數 3271 閱讀 8913

querycache(下面簡稱qc)是根據sql語句來cache的。乙個sql查詢如果以select開頭,那麼mysql伺服器將嘗試對其使用qc。每個cache都是以sql文字作為key來存的。

原理

querycache(下面簡稱qc)是根據sql語句來cache的。乙個sql查詢如果以select開頭,那麼mysql伺服器將嘗試對其使用qc。每個cache都是以sql文字作為key來存的。在應用qc之前,sql文字不會被作任何處理。也就是說,兩個sql語句,只要相差哪怕是乙個字元(例如大小寫不一樣;多乙個空格等),那麼這兩個sql將使用不同的乙個cache。 

不過sql文字有可能會被客戶端做一些處理。例如在官方的命令列客戶端裡,在傳送sql給伺服器之前,會做如下處理:  

過濾所有注釋

去掉sql文字前後的空格,tab等字元。注意,是文字前面和後面的。中間的不會被去掉。  

下面的三條sql裡,因為select大小寫的關係,最後一條和其他兩條在qc裡肯定是用的不一樣的儲存位置。而第一條和第二條,區別在於後者有個注釋,在不同客戶端,會有不一樣的結果。所以,保險起見,請盡量不要使用動態的注釋。在php的mysql擴充套件裡,sql的注釋是不會被去掉的。也就是三條sql會被儲存在三個不同的快取裡,雖然它們的結果都是一樣的。  

select * from people where name='test';  

select * from people where /*hey~*/name='test';  

select * from people where name='test';  

目前只有select語句會被cache,其他類似show,use的語句則不會被cache。

儲存塊

在本節裡「儲存塊」和「block」是同乙個意思 

qc快取乙個查詢結果的時候,一般情況下不是一次性地分配足夠多的記憶體來快取結果的。而是在查詢結果獲得的過程中,逐塊儲存。當乙個儲存塊被填滿之後,乙個新的儲存塊將會被建立,並分配記憶體(allocate)。單個儲存塊的記憶體分配大小通過query_cache_min_res_unit引數控制,預設為4kb。最後乙個儲存塊,如果不能被全部利用,那麼沒使用的記憶體將會被釋放。如果被快取的結果很大,那麼會可能會導致分配記憶體操作太頻繁,系統系能也隨之下降;而如果被快取的結果都很小,那麼可能會導致記憶體碎片過多,這些碎片如果太小,就很有可能不能再被分配使用。 

除了查詢結果需要儲存塊之外,每個sql文字也需要乙個儲存塊,而涉及到的表也需要乙個儲存塊(表的儲存塊是所有執行緒共享的,每個表只需要乙個儲存塊)。儲存塊總數量=查詢結果數量*2+涉及的資料庫表數量。也就是說,第乙個快取生成的時候,至少需要三個儲存塊:表資訊儲存塊,sql文字儲存塊,查詢結果儲存塊。而第二個查詢如果用的是同乙個表,那麼最少只需要兩個儲存塊:sql文字儲存塊,查詢結果儲存塊。 

通過觀察qcache_queries_in_cache和qcache_total_blocks可以知道平均每個快取結果占用的儲存塊。它們的比例如果接近1:2,則說明當前的query_cache_min_res_unit引數已經足夠大了。如果qcache_total_blocks比qcache_queries_in_cache多很多,則需要增加query_cache_min_res_unit的大小。 

qcache_queries_in_cache*query_cache_min_res_unit(sql文字和表資訊所在的block占用的記憶體很小,可以忽略)如果遠遠大於query_cache_size-qcache_free_memory,那麼可以嘗試減小query_cache_min_res_unit的值。

調整大小

如果qcache_lowmem_prunes增長迅速,意味著很多快取因為記憶體不夠而被釋放,而不是因為相關表被更新。嘗試加大query_cache_size,盡量使qcache_lowmem_prunes零增長。

啟動引數 

show variables like 'query_cache%'可以看到這些資訊。 

query_cache_limit:如果單個查詢結果大於這個值,則不cache  

query_cache_size:分配給qc的記憶體。如果設為0,則相當於禁用qc。要注意qc必須使用大約40kb來儲存它的結構,如果設定小於40kb,則相當於禁用qc。qc儲存的最小單位是1024 byte,所以如果你設定了乙個不是1024的倍數的值,這個值會被四捨五入到最接近當前值的等於1024的倍數的值。  

query_cache_type:0 完全禁止qc,不受sql語句控制(另外可能要注意的是,即使這裡禁用,上面乙個引數所設定的記憶體大小還是會被分配);1啟用qc,可以在sql語句使用sql_no_cache禁用;2可以在sql語句使用sql_cache啟用。  

query_cache_min_res_unit:每次給qc結果分配記憶體的大小  

狀態 show status like 'qcache%'可以看到這些資訊。 

qcache_free_blocks:當乙個表被更新之後,和它相關的cache blocks將被free。但是這個block依然可能存在佇列中,除非是在佇列的尾部。這些blocks將會被統計到這個值來。可以用flush query cache語句來清空free blocks。  

qcache_free_memory:可用記憶體,如果很小,考慮增加query_cache_size  

qcache_hits:自mysql程序啟動起,cache的命中數量  

qcache_inserts:自mysql程序啟動起,被增加進qc的數量  

qcache_lowmem_prunes:由於記憶體過少而導致qc被刪除的條數。加大query_cache_size,盡可能保持這個值0增長。  

qcache_not_cached:自mysql程序啟動起,沒有被cache的唯讀查詢數量(包括select,show,use,desc等)  

qcache_queries_in_cache:當前被cache的sql數量  

qcache_total_blocks:在qc中的blocks數。乙個query可能被多個blocks儲存,而這幾個blocks中的最後乙個,未用滿的記憶體將會被釋放掉。例如乙個qc結果要佔6kb記憶體,如果query_cache_min_res_unit是4kb,則最後將會生成3個blocks,第乙個block用來儲存sql語句文字,這個不會被統計到query+cache_size裡,第二個block為4kb,第三個block為2kb(先allocate4kb,然後釋放多餘的2kb)。每個表,當第乙個和它有關的sql查詢被cache的時候,會使用乙個block來儲存表資訊。也就是說,block會被用在三處地方:表資訊,sql文字,查詢結果。 

mysql的恢復 MYSQL的恢復

恢復就簡單多了!只要執行該備份檔案就行了,該備份檔案是sql哦!恢復完全備份mysql uroot p backup.sql 就這麼簡單!恢復增量備份mysqlbinlog mysql bin.000002 mysql u root p 注意此次恢復過程亦會寫入日誌檔案,如果資料量很大,建議先關閉日...

mysql的查詢日誌 mysql

這篇文章總結了mysql中查詢日誌的知識點。mysql中,日誌可以按照功能分為如下幾類。錯誤日誌 查詢日誌 慢查詢日誌 二進位制日誌 中繼日誌 innodb儲存引擎級別的事務日誌 查詢日誌 查詢日誌在mysql中被稱之為general log 通用日誌 不要被 查詢日誌 的名字誤導,錯誤的以為查詢日...

mysql的定義 MySQL定義

什麼是sql sql是結構化查詢語言。什麼是資料庫 資料庫是用來儲存資料的。關聯式資料庫 多張表之間的關係。關聯式資料庫包含表 表名 列 主鍵,通過相應的關係列來產生連線關係。資料庫與資料倉儲 資料庫是用來做交易 transaction 資料倉儲是用來做分析 analytics 資料倉儲的作用在於 ...