高性能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—