史上最全MySQL參數調優及資料庫鎖實踐
1. 應用優化
對於訪問資料庫來說,建立連接的代價是比較昂貴的,因為我們頻繁的創建關閉連接,是比較耗費資源的,我們有必要建立資料庫連接池,以提高訪問的性能。
1.2 減少對MySQL的訪問
1.2.1 避免對數據進行重複檢索
在編寫應用代碼時,需要能夠理清對資料庫的訪問邏輯。能夠一次連接就獲取到結果的,就不用兩次連接,這樣可以大大減少對數據無用的重複請求。
1.2.2 增加cache層
在應用中,我們可以在應用中增加緩存層來達到減輕資料庫負擔的目的。緩存層有很多種,也很有很多實現方式,只要能達到資料庫的負擔又能滿足應用需求就可以。
1.3 負載均衡
負載均衡是應用中使用非常普遍的一種優化方法,它的機制就是利用某種均衡演算法,將固定的負載量分佈到不同的伺服器上,以此來降低單臺伺服器的負載,達到優化的效果。
1.3.1 利用MySQL複製分流查詢
通過MySQL的主從複製,實現讀寫分離,使增刪改操作走主節點,查詢操作走從節點,從而可以降低單臺伺服器的讀寫壓力。
1.3.2 採用分散式數據架構
分散式資料庫架構適合大數據量、負載高的情況,它有良好的拓展性和高可用性。通過在多臺伺服器之間分佈數據,可以實現在多臺伺服器之間的負載均衡,提高訪問效率。
2. MySQL中查詢緩存優化
2.1 概述
開啟MySQL的查詢緩存,當執行完全相同的SQL語句的時候,伺服器就會直接從緩存中讀取結果,當數據被修改,之前的緩存會失效,修改比較頻繁的表不適合做查詢緩存。
2.2 操作流程
2.3 查詢緩存配置
1.查看當前的MySQL資料庫是否支持查詢緩存 :
SHOW STATUS LIKE 『Qcache%』;
2.4 開啟查詢緩存
MySQL的查詢緩存默認是關閉的,需要手動配置參數query cache type,來開啟查詢緩存。query cache type該參數的可取值有三個 :
3)DEMAND或2 :查詢緩存功能按需進行,顯示指定SQL_CACHE的SELECT語句才會緩存;其他均不予緩存。
2.5 查詢緩存SELECT選項
可以在SELECT語句中指定兩個與查詢緩存相關的選項 :
例子 :
2.6 查詢緩存失效的情況
1)SQL語句不一致的情況,要想命中查詢緩存,查詢的SQL語句必須一致。
3)不使用任何錶查詢語句。
3. MySQl內存管理及優化
3.1 內存優化原則
1)將盡量多的內存分配給MySQL做緩存,但要給操作系統和其他程序預留足夠內存。
3)排序區、連接區等緩存是分配給每個資料庫會後(session)專用的,其默認值的設置要根據最大連接數合理分配,如果設置太大,不但浪費資源,而且在並發連接較高時會導致物理內存耗盡。
3.2 MyISAM內存優化
myisam存儲引擎使用key_buffer緩存索引塊,加速myisam索引的讀寫速度。對於myisam表的數據塊,mysql沒有特別的緩存機制,完全依賴於操作系統的IO緩存。
key_buffer_size
read _buffer_size
read_rnd_buffer_size
3.3 InnoDB內存優化
innoDB用一塊內存區做IO緩存池,該緩存池不僅用來緩存innodb的索引塊,而且也用來緩存innodb的數據塊。
innodb_buffer_pool_size
innodb_log_buffer_size
4. MySQL並發參數調整
從實現上來說,MySQL Server是多線程結構,包括後臺線程和客戶服務線程。多線程可用有效利用伺服器資源,提供資料庫的並發性能。
4.1 max_connections
採用max_connections控制允許連接到MySQL資料庫的最大數量,默認值時151.如果狀態變數connection_errors_max_connections不為零,並且一直增長,則說明不斷有連接請求因資料庫連接數已達到允許最大值而失敗,這是可以考慮增大max_connections的值。
4.2 back_log
back_log參數控制MySQL監聽TCP埠時設置的積壓請求棧大小。如果MySQL的連接數達到max_connections時,新來的請求將會被存在堆棧中,以等待某一連接釋放資源,該堆棧的數量即back_log,如果等待連接的數量超過back_log,將不被授予連接資源,將會報錯。5.6.6版本之前默認值為50,之後的版本默認為50+(max_connections / 5),最大不超過900。
4.3 table_open_cache
該參數用來控制所有SQL語句執行線程可打開表緩存的數量,而在執行SQL語句時,每一個SQL執行線程至少要打開1個表緩存。該參數的值應該根據設置的最大連接數mac_connections以及每個連接執行關聯查詢中涉及的表的最大數量來設定 :
4.4 thread_cache_size
為了加快連接資料庫的速度,MySQL會緩存一定數量的客戶服務線程以備重用,通過參數thread_cache_size可控制MySQL緩存客戶服務線程的數量。
4.5 innodb_lock_wait_timeout
該參數是用來設置InnoDB事務等待行鎖的時間,默認值是50ms,可以根據需要進行動態設置。對於需要快速反饋的業務系統來說,可以將行鎖的等待時間調小,以避免事務長時間掛起;對於後臺運行的批量處理程序來說,可以將行鎖的等待時間調大,以避免發生大的回滾操作。
5. MySQl鎖問題
5.1 鎖概述
鎖是計算機協調多個進程或線程並發訪問某一資源的機制。
5.2 鎖分類
從對數據操作的粒度分:
5.3 MySQL鎖
相對其他資料庫而言,MySQL的鎖機制比較簡單,其最顯著的特點是不同的存儲引擎不同的鎖機制。下表中羅列出了各存儲引擎對鎖的支持情況 :
5.2 MyISAM表鎖
MyISAM存儲引擎只支持表鎖,這也是MySQL開始幾個版本中唯一支持的鎖類型。
5.2.1 如何加表鎖
MyISAM在執行查詢語句(SELECT)前,會自動給涉及的所有表加讀鎖,在執行更新操作(UPDATE、DELETE、INSERT等)前,會自動給涉及的表加寫鎖,這個過程並不需要用戶幹預,因此,用戶一般不需要直接用LOCK TABLE命令給MyISAM表顯示加鎖。
5.2.4 結論
鎖模式的相互兼容性如表中所示 :
5.2.5 查看鎖的爭用情況
show open tables;
5.3 InnoDB行鎖
5.3.1 行鎖介紹
行鎖特點 :偏向InnoDB存儲引擎,開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的概率最低,並發度也最高。
5.3.2 背景知識
事務及其ACID屬性
5.3.3 InnoDB的行鎖模式
InnoDB實現了以下兩種類型的行鎖。
5.3.6 無索引行鎖升級為表鎖
如果不通過索引條件檢索數據,那麼InnoDB將對表中的所有記錄加鎖,實際效果更表鎖一樣。
5.3.7 間隙鎖危害
當我們用範圍條件,而不是使用相等條件檢索數據,並請求共享或排他鎖時,InnoDB會給符合條件的已有數據進行加鎖;對於鍵值在條件返回內但並不存在的記錄,叫做「間隙(GAP)」,InnoDB也會對這個「間隙」加鎖,這種鎖機制就是所謂的間隙鎖(Next-Key鎖)。
5.3.8 InnoDB行鎖爭用情況
show status like 『innodb_row_lock%』;
5.3.9 總結
InnoDB存儲引擎由於實現了行級鎖定,雖然在鎖定機制的實現方面帶來了性能損耗可能比表鎖會更高一些,但是在整體並發處理能力方面要遠遠優於MyISAM的表鎖的。當系統並發量較高時,InnoDB的整體性能和MyISAM相比就會有比較明顯的優勢。
6. 常用SQL技巧
6.1 SQL執行順序
編寫順序
6.2 正則表達式
正則表達式(Regular Expression)是指一個用來描述或者匹配一系列符合某個句法規則的字元串的單個字元串。
6.3 MySQL常用函數
數字函數