高性能MySQL之快取

  • 2019 年 11 月 11 日
  • 筆記

10

Nov,2019

雙十一仔細想了想,好像也沒什麼可買的,吃的零食什麼的都還有,用的東西沒什麼缺的,想想還是算了吧,還不如早點搞完早點休息來的實在。個人感覺已經過了衝動消費的年紀了,這可能也是人老了的標誌吧。。。

高性能MySQL之快取

MySQL中的快取是用來避免所查詢的數據需要對磁碟進行訪問,我們知道,磁碟上的訪問會比記憶體的訪問速度慢得多,所以,如果你的伺服器上之部署了一個MySQL的服務,那麼為它配置一個大的快取無疑是明智之舉。

在MySQL中,常用的快取類型包含以下幾種:

1、Innodb緩衝池

2、Innodb日誌文件和MyISAM數據的作業系統快取

3、MyISAM鍵快取

4、查詢快取

今天我們簡單介紹其中的1、2、4三類。

如果我們的MySQL伺服器之設置了MyISAM一種存儲引擎,那麼我們完全可以關閉Innodb的各種配置,如果只使用了innodb存儲引擎,則需要配置一部分MyISAM的記憶體資源,因為系統表中有些是使用的是MyISAM。如果大部分都是Innodb表,那麼innodb緩衝池的大小就基本上決定了我們MySQL資料庫的性能,我們知道,innodb緩衝池中並不僅僅快取索引,還包含插入緩衝、鎖資訊等其他數據結構,innodb存儲引擎是嚴重依賴緩衝池的。

如果數據量不大,而且不會快速增長,那麼一個小的緩衝池其實也可以接受,也建議這麼做。因為大的緩衝池除了會帶來性能上的提升之外,還會帶來一些問題。例如,數據的預熱和實例的關閉都會花費很長時間,如果有很多"臟頁"在緩衝池中,那麼實例關閉的時候需要將這些臟頁刷新回磁碟,就會導致實例的關閉時間比較長。當然,你會說,innodb可以強制關閉,這樣是臨時解決了關閉上的問題,但是當實例重啟的時候,又會花費很多的時間進行恢復。我們可以在關閉實例之前,通過修改參數innodb_max_dirty_pages_pct的方法來講臟頁所佔的百分比來減小,這樣可以加速接下來的關閉過程。

當我們的存儲引擎是MyISAM的時候,key_buffer_size這個參數就顯得很重要了,這個參數代表的是鍵緩衝,如果MyISAM的表比較多,那麼這個值應該設置的比較大,當然,也不是無限大,一般來講,這個值最大不超過當前MyISAM索引所佔的大小。默認情況下,MyISAM將所有的索引都快取在默認的鍵快取中,當然,這個值我們可以在配置文件中手動設置。最後,也是重要的一點,MyISAM中,索引是快取在建快取中的,而數據文件是快取在作業系統的快取中的,查詢語句中索引的命中和數據的命中二者是不相關的

MySQL在解析一個查詢之前,如果查詢快取是打開的,則會首先在查詢快取中去查找是否命中快取,當發現查詢命中快取之後,會檢查一遍許可權(注意,此時該查詢語句並沒有被解析,不用生成執行計劃,不用被執行),如果許可權沒問題,那麼MySQL將會跳過所有的階段,直接從快取中拿到結果並返回給客戶端。在MySQL中,用於查詢快取的記憶體被分成了一個個的數據塊,這些數據塊中存儲了自己的類型,大小和存儲的數據本身,除了這些數據塊之外,還有一個元數據維護的數據結構,當有查詢結果需要快取的時候,MySQL先從大的空間中申請一個數據塊用於存儲數據結果,這個數據塊的大小是由參數query_cache_min_res_unit決定的,到這裡,我們知道MySQL無法為每一個查詢的結果精確分配恰好匹配的快取空間。隨著並發查詢的進行,在查詢快取中也會出現記憶體碎片。

當然,我們可以根據實際情況來設置參數query_cache_min_res_unit的值,如果這個值query_cache_min_res_unit設置的很小,理論上浪費的空間就比較小,但是記憶體塊的申請操作會變得比較頻繁,影響資料庫的性能,如果這個值設置的很大,那麼查詢快取中的記憶體碎片會增多。

我們知道,查詢快取是為了提高查詢的性能,但是如果你的查詢每次都不一樣,查詢快取的命中率過低,那麼查詢快取有可能沒有起到正向的效果,所以,查詢快取不一定會提高查詢的效率,只有在查詢快取帶來的資源節約大於其本身的資源小韓的時候,才會給系統帶來性能提升。最後,我們介紹幾個查詢快取的參數:

query_cache_type,這個參數控制是否打開查詢快取,可以設置為on、off或者demand,demand是指需要手工顯示指定sql_cache的語句才放入查詢快取。

query_cache_size:這個參數是指查詢快取使用的總記憶體空間,單位是位元組,一般MySQL會將其設置為1024的倍數。

query_cache_min_res_unit,這個參數上面說過了。

query_cache_limit,這個參數是指能夠快取的最大查詢結果,如果查詢結果大於這個值,則不會被快取。

query_cache_wlock_invalidate,如果某個數據表被其他的連接鎖住,是否仍然需要從查詢快取中返回結果,默認值是off,意思是資料庫將返回其他執行緒鎖住的數據,如果設置為on,則不會從快取中返回這類數據,會等待鎖的釋放。

—END—