什麼是性能優化呢?其實咱們每每從廣義的定義是以爲一個MySQL系統的非功能性的優化都會看做是性能優化,好比咱們會將數據庫服務器的穩定性、每秒執行的SQL查詢數目、系統的可擴展性、cpu利用率等等特性的優化都會當作是MySQL的性能優化。 前端
我我的比較贊同本書的觀點是MySQL性能優化應該就是指MySQL的查詢響應時間的優化,MySQL性能優化就是將查詢響應時間優化到一個客戶或者用戶體驗可以接受的一個程度。 mysql
書中提到一個「基於目標的性能優化」的這個觀點我是很是認同的,那麼咱們在這裏討論一下,爲何要基於目標進行優化呢?咱們設想一下,當咱們沒有目標或者目標不明確的時候,好比咱們的目標設定爲將MySQL的性能優化到儘量地快。這樣的目標設定的時候,咱們在執行具體的性能優化工做的時候就不知道該如何選擇和排優先級了,影響性能的因素很是多,可以提高性能的工做也很是多,若是咱們不加選擇,每一項都去作,則將耗費很是高的成本,而這每每是不可行的,成本在一個商業組織裏永遠是有限的。若是咱們選擇不當的時候,極可能咱們花費了大量的成本用在那些受益很是低的優化工做裏,我相信這樣的選擇和作法絕對是不明智的,甚至是錯誤的。而性能優化這個領域也大體是遵循2/8原則的,也就是說80%的性能問題集中在20%的緣由上,所以咱們將成本花費在找到這20%的緣由並解決這些性能問題將能得到80%的受益將會是一個很是明智的選擇。 ios
所以性能優化不是一場理想主義者對技術完美的追求,也不是一場不計成本的技術試驗,它其實就是一場爲達成目標而進行的商業活動,這個目標也通常是對外的,它多是爲了讓用戶響應時間達到500毫秒,也多是讓產品響應時間比其它競品快50毫秒。它不是爲了永無止境的追求完美,讓系統的性能達到極致。所以咱們在作性能優化的時候還要充分考慮到投入產出比,作出更加明智的選擇。 sql
性能優化流程應該是通用的,也一樣適用於應用優化或者其它中間件的優化,而性能優化技術涉及到一些具體的工具和技術,通用性不強,但思路也是能夠互相借鑑的。 數據庫
另外具體的優化工具指針對Linux操做系統,由於互聯網公司的MySQL生產絕大多數運行在Linux上,所以忽略其它OS平臺。 性能優化
我認爲優化目標應該從用戶出發,好比MySQL的用戶是上游的調用方,即發出查詢語句的應用程序,從上游得到優化目標,好比上游的指望是優化目標是達到響應時間的範圍,若是上游沒法肯定的時候則應該繼續再往上游找,則找到的可能就是前端應用,若是依然沒法肯定,則就是使用應用的用戶對於性能的指望,根據產品要求以及競品分析綜合分析出性能需求。而後反向推導出對於MySQL的性能優化目標。最終獲得MySQL的SQL語句的性能優化目標是相似於這樣的: 服務器
在10月30日以前達到QPS1000的時候而且TP99小於10毫秒的目標。 網絡
設定的優化目標一樣應該遵循SMART原則,即要求它是具體的(明確無歧義的,相關參與者都可以達成共識)、可衡量的(儘量有數據來衡量目標)、可達到的(通常是在比較有把握的基礎上增長20%的挑戰)、其它目標相關的(對於產品和業務整體目標有促進做用)、有明確截至時間的。 按照這個原則去要求和修正本身的目標設定。 工具
固然目標可能不是一蹴而就的,每每須要屢次迭代才能得到更加準確合理的目標。 性能
在影響MySQL性能的因素裏能夠首先分爲宏觀和微觀的兩大類,宏觀的就是會影響幾乎全部SQL的性能因素,好比一些共享的硬件資源(網絡、CPU、內存、CPU等等)和軟件資源(好比操做系統的資源限制配置、MySQL的執行線程、數據庫鎖)等等,這些宏觀的因素對於MySQL的影響是全局的,它的影響範圍比較廣,所以這些性能問題因素的消除,它的收益相對微觀因素是更高的;微觀因素通常是指影響某一條或者少數幾條SQL的性能因素,這些因素多是SQL語句的執行復雜度過高或者在等待其它鎖的釋放等等。
本章節不詳細介紹這些命令的具體用法,詳細用法請參考相關的手冊。
1.宏觀系統測量
top Linux系統命令
查看系統啓動信息、任務統計信息、cpu和內存等統計信息,還有進程的列表信息。這裏咱們能夠重點關注mysqld進程的信息,對整個服務器系統有一個較爲全面的瞭解。
iostat Linux系統命令
該命令能夠監控Linux服務器上設備的io負載狀況。經過查看負載,發現那些比較異常的磁盤io負載現象,經過一些異常數據的捕獲可以發現問題的一些緣由。好比mysql的磁盤io頻繁,可能成爲系統的性能瓶頸。
show global status MySQL命令。
該命令能夠查看MySQL服務器的各類運行狀態的彙總,能夠重點關注與本次優化目標相關的狀態數據進行分析。
show processlist MySQL命令。
該命令能夠查看MySQL服務器執行線程的狀態,重點關注哪些執行時間長的、阻塞狀態的線程,分析這些線程上所運行的SQL語句。
查看MySQL慢查詢日誌
經過分析和查看慢查詢日誌,重點關注兩類慢查詢,執行比較耗時(好比大於100毫秒)執行很是頻繁的;查詢很是耗時(2000毫秒)的查詢。這兩類查詢都是對於整個系統影響很是大的語句,重點分析和優化這樣的SQL語句。具體選擇哪些進行優化,還應該結合目標。
2.微觀查詢測量
explain
該命令時MySQL中用語分析select查詢語句的執行計劃的命令,經過該命令加上查詢語句能夠分析MySQL的執行計劃,它使用哪一個索引進行查詢,有沒有使用臨時表,查詢須要便利的記錄數都會列舉出來,通常經過該命令的分析都能查找出select語句性能差的緣由,對於單條查詢語句的優化這是一個很是好的工具。應該帳號它。
show profile
該命令能夠詳細列舉出執行某一個查詢的每個執行步驟的耗時分析,這對於深刻優化某一個SQL語句很是有幫助,它時做爲explian的一個重要的補充。
具體的分析方法本文不一一列舉出,只討論一下通用的原則和方法。
咱們經過上一步的各類測量工具的數據捕獲以後,就能夠對這些各類狀態和數據進行剖析,分析出性能的根本緣由,那本文描述的一些通用的注意事項和原則是這樣的。
1.測量的數據可能會有遺漏或者不許確。多是工具的侷限性或者工具自己的問題,會存在數據的不許確或遺漏,這個客觀事實是要注意的。
2.剖析應該先用工具進行彙總,原則是先宏觀再微觀。
3.根據數據分析性能問題的緣由。咱們經過分析數據,找到一些異常的數據,對這些異常的數據的現象分析產生的緣由。
4.針對根本緣由設計優化方案。對症下藥才能藥到病除,通常不建議沒有找到原則就根據猜想就設計幾個方案去逐一嘗試,這種嘗試的方法成本是很是高的,固然也不是絕對的,在實在沒法找到緣由的時候也不失爲一種最後的解決方案。
上一步得出的結論是性能問題的緣由和對應的解決方案,這一步咱們實施優化方案。實施方案通常應該選擇在線下的模擬測試環境,或者線上的灰度測試環境上進行。不可以影響生產使用,並且原則是性能優化方案不能影響原來的功能的正確性,而且同時在實施的同時要考慮增長響應的監控點,這些監控點的目的就是收集數據,以驗證優化方案的有效性。
把優化方案實施後的系統再進行一遍測量,記錄下優化方案實施後的測試量數據。
將測量後的數據與優化前的進行對比,評估一下優化方案的有效性,是否達到了優化目標。
若已經達到了優化則能夠中止進行優化了,切忌要抵制住完美主義的情節。
若未達成目標則要分析和溝通是否還要進一步進行優化,則能夠繼續執行3-5步循環迭代,直到結束爲止。