10個提升MySQL效能的小技巧

小y發表於2017-08-04

從工作量分析到索引的三條規則,這些專家見解肯定會讓您的MySQL伺服器尖叫。

在所有的關聯式資料庫中,MySQL已經被證明了完全是一頭野獸,只要通知停止執行就絕對不會讓你多等一秒鐘,使你的應用置於困境之中,你的工作也承受極大的風險。

不過事實是,普通的錯誤都在MySQL效能錯誤的射程之內。所以為了使你的MySQL伺服器能夠高速運轉,提供穩定且持續的服務,消除這些錯誤是非常有必要的,但是這可能常常會被你的繁忙工作或配置陷阱微妙地遮蔽了。

幸運的是,許多MySQL效能問題其實都有相似的解決辦法,發現並解決問題,然後你的MySQL用起來就順手多啦。

接下來就和大家分享一下10個使MySQL效能提升的小技巧。

MySQL效能提升小技巧1:對你的工作進行配置 

想要了解你的伺服器到底如何支配時間,最好的辦法就是對伺服器的工作進行配置。通過配置你的伺服器,你可以expose最昂貴的query來為將來的調優做準備。從這個角度,時間就是最重要的衡量標準,因為當你對你的伺服器發起一個query之後,除了它到底多塊的完成之外你不會關心任何其他事。

配置你的工作檔案的最優解就是MySQL Enterprise Monitor的query分析儀或者Percona Toolkit的pt-query-digest。這些工具可以幫助你捕捉你的伺服器正在執行的詢問以及返回按響應時間遞減順序排序的任務表,它還會持續不斷地把最昂貴、費時的任務更新在最上方,這樣你就能知道你的精力應該更加集中在什麼地方了。

工作檔案配置工具會把相似的詢問分在一個組,你可以很方便地檢視低速執行或者是告訴執行但是多次進行的詢問。

MySQL效能提升小技巧2: 深入理解四個基本資源

一個資料庫伺服器需要以下4種資源才能正常運轉:CPU,記憶體,硬碟以及網路。如果這其中任何一種效能不足,運轉不力或者超負荷運轉的話,那麼資料庫伺服器就非常可能表現不佳。

理解基礎的資源是非常重要是以下兩個層面:選擇硬體以及疑難問題解答。

當為MySQL選擇硬體的時候,確保所有的元件都表現良好。同樣重要的是把它們進行合理的配置。大多是時候,一些機構會選擇高轉速的CPU以及硬碟,但是他們通常來講記憶體都不夠用。在某些情況下,按照數量級增加記憶體是提升效能最廉價的辦法,尤其是工作負載是繫結磁碟的情況下。這聽起來可能違反常識,但是在許多情況下,硬碟都是過度使用的,因為沒有足夠的記憶體來儲存資料工作集。

另外一個平衡的典範當屬CPU。在大多數情況下,MySQL使用高轉速的CPU會運轉得很好,因為每一個詢問都是在單執行緒中執行而不能在CPU之間並行。

當要解答疑難問題的時候,請了解清楚所有資源的效能和使用情況,用你審慎的目光來判斷它們到底是本來就效能差勁還是因為承載了過多的任務。這個姿勢應該能讓你解決問題快一些。

MySQL效能提升小技巧3:別吧MySQL當成一個佇列使

佇列和佇列訪問模式可以在你完全沒有察覺的情況下偷偷進入你的應用。舉個栗子,如果你設定了某個項的狀態,以便某個特定的工作程式在呼叫它之前可以宣告它,那麼你就在無意中建立了一個佇列。把郵件標記為未傳送,傳送它們,然後它們被標記為已傳送就是一個很好理解的栗子。

佇列會產生問題主要有2個原因:它們連續運轉你工作,防止它們並行,那麼這通常就會產生一個表格,裡面包含了程式中的工作還有很久以前已完成工作的歷史資料。這不僅會使你的應用產生延遲而且也會給MySQL增加不必要的負荷。

MySQL效能提升小技巧4: 花費最少的結果先過濾

優化MySQL效能最好的辦法就是先完成廉價、不確定的工作,然後在最小的結果資料集中完成艱難、準確的工作。

例如你要通過一個給定的地理位置半徑來找到你想要的東西。在大多數程式設計師的工具箱裡,他們首先會想到的一定是計算球面上的距離的大圓公式(Haversine)。但是用這個公式的問題在於可能要用到很多三角方面的運算,這對CPU的要求是非常高的。大圓的計算往往執行緩慢,使得機器的CPU使用率飆升。

在你開始應用大圓公式之前,在總集當中將你的記錄減少成最小的子集,並把結果集整合成一個確切的圓。一個包含圓(確切或不確切的)的正方形是解決這個問題最簡單的方法。這樣的話,正方形之外的一切都不回碰上這些成本昂貴的三角函式。

MySQL效能提升小技巧5:瞭解兩種伸縮性死亡陷阱

伸縮性其實並不像你想象的那樣捉摸不定。實際上在數學當中已經有非常明確的將伸縮性表示為方程式的定義。這些方程式突出展現了為什麼系統並沒有如預期那樣的良好伸縮。

參見通用可擴充套件法(Universal Scalability Law)—非常清晰地解釋和量化了一個系統的伸縮性特性。它從兩個基礎成本方面對伸縮性問題進行了闡釋:序列化(serialization)和串擾(crosstalk)。

多程式必須為在伸縮性上具有固有限制的序列化停止工作。相似地,如果多個程式必須時時刻刻互相交流才能配合他們的工作的話,他們就是在互相限制。

避免序列化以及串擾,你的應用伸縮性將會大大提升。那麼在對MySQL來說意味著什麼呢?因情況而異,但有些示例可以避免對行進行排它鎖定。關於佇列,參見技巧3,往往會因為佇列伸縮性就變得很差。

MySQL效能提升小技巧6:不要太關注配置 

DBA常常耗費大量的時間來調整配置。換來的結果有時卻是傷害而不是大的提升。我看到過許多的最優化的伺服器時不時就崩潰,記憶體不足,而且在工作負載稍微多一點的時候就表現很差。

MySQL上搭載的預設配置是一刀切並且嚴重過時的,但是它們也不需要完全重新配置。只要把最基礎的設定正確,有需要的話再做小幅調整即可。在大多數情況下,通過正確設定大約10個選項,你可以獲得伺服器峰值效能的95%。其他無法應用此方法的的情況的話應該是非常特殊的情況,所以就不用去管他了。

在大多數情況下,伺服器“轉換”工具是不推薦的,因為它們常常會有一些在特定情況下並不適用的規則。有些甚至存在危險且不準確編碼—例如快取命中率和記憶體消耗公式。這些都是不對的,而且隨這時代的進步他們變得更加地不對。

MySQL效能提升小技巧7: 小心分頁詢問

分頁應用常常會把伺服器搞癱瘓。在向你展示結果的頁面當中,有翻到下一頁的連結,這類應用通常不以索引的方式進行分類整理,然後他們使用一種 LIMIT和 offset使得伺服器做大量的工作生成,然後丟棄行。

優化選項在使用者介面常常自己就能找到。而不是展示確切的頁數結果以及每個頁面的單獨連結,只展示下一列的連結就好。你也可以防止大家翻到太后面的頁數。

從質詢方面來看,你可以比你想要的多選取一行,然後當你點選“下一頁”連結的時候,你可以指定最後一行作為下一組結果的起點,而不是使用帶offset的 LIMIT。舉個栗子,當使用者在檢視120行中的第101行時,你會同時select第121行;為了遞交下一頁,你可以向伺服器詢問第121行或者超過121的行,限定在21。

MySQL效能提升小技巧8: 及時儲存資料,審慎警告

監管和預警是必不可少的,但是典型的監控系統到底怎麼了?它開始傳送一些錯誤的手勢,然後系統管理員就設定了垃圾郵件過濾規則來停止這些煩擾。然後很快你的監管系統就會完全癱瘓。

我傾向於從兩個方面來看待監管;獲取指標以及發出預警。儘可能的獲取並儲存指標是非常重要的,因為當你想要知道系統到底改變了什麼的時候你會很慶幸你當初儲存了它們。有一天會突然出現一個很奇怪的錯誤,然後你就會很高興你有能力指出伺服器的工作負載中的一段然後展示這個改變。

相比之下,警告就可能有點多了。人們常常會對快取命中率或者短期內每秒所建立的表格發出警告。問題是對這種快取命中率並沒有一個合適的閾值。正確的閾值並不是隨著伺服器的不同而變化,而是隨著你工作負載的不同,每一個小時都是不一樣的。

這就導致,警告只能有節制地並且只能在預示一個具體、可操作的問題時才是可行的。一個低快取命中率並不是可操作的問題,而且他也不指向一個實在的問題,但對連線嘗試沒有響應的伺服器才是真正需要結局的問題。

MySQL效能提升小技巧9: 學習index的三條法則

Index可能是資料庫彙總最難理解的概念,因為很容易就對Index到底如何工作以及伺服器如何使用它們感到困惑。確實要花些力氣才能真正理解它到底是怎麼回事。

Index經過適當設計後,主要在資料庫伺服器中提供如下三種服務:

  1. Index讓伺服器查詢相鄰行的集合而不是單獨的行。許多人可能會認為index的作用就是為了查詢單獨的行,但是查詢單獨的行會導致混亂的硬碟操作,速度就會變慢。而且查詢行的集合要容易多了,所有或者說大多數都比一次只查詢一個行要有趣多了。

  2. Index通過按照閱讀喜好進行排列省去了整理的過程。整理是耗費巨大的。按照自己的喜好進行閱讀效率也更高。

  3. Index完全滿足了伺服器的詢問,根本就不需要再連線表格。這是眾所周知的覆蓋索引或僅索引查詢。

如果你可以定義自己的索引和詢問來利用這三個機會,你就可以使查詢速度快幾個數量級。

MySQL效能提升小技巧10: 利用同行的專業知識

不要一個人冒險。如果你對一個問題感到煩惱,同時也在做一些對你來說有邏輯且隔離的解決方式,那很好。這在20次中可能會有19次是有效的。但是剩下的1次,你可能會掉進兔子洞裡,會非常費時費力,這完全是因為你現在所做的努力只是看起來可能是有意義的。

建立與MySQL相關的資源網路,這超越了工具和故障排除指南。有一些非常有知識的人潛伏在郵件列表、論壇、問答網站上,等等。會議、展會和本地使用者團體活動都提供了寶貴的機會,讓你能與那些在緊要關頭幫助你的同行建立聯絡。

相關文章