一.myisam存儲引擎鎖優化
mysql
1.合理理由讀寫優先級sql
MyISAM 的表鎖,寫互相阻塞的表鎖,併發
默認系統是寫優先,可改成讀有先:ide
low_priority_updates=1性能
若是咱們的系統是一個以讀爲主,並且要優先保證查詢性能的話,能夠經過設置系統參數選項優化
low_priority_updates=1,將寫的優先級設置爲比讀的優先級低,便可讓告訴MySQL 儘可能先處理讀請設計
求。索引
若系統須要有限保證數據寫入的性能的話,則能夠不用設置low_priority_updates事件
參數了。事務
2.分離能並行的操做
Concurrent Insert(併發插入)的特性:
MyISAM 存儲引擎有一個控制是否打開Concurrent Insert 功能的參數選項:concurrent_insert,可
以設置爲0,1 或者2。三個值的具體說明以下:
a) concurrent_insert=2,不管MyISAM 存儲引擎的表數據文件的中間部分是否存在由於刪除數據
而留下的空閒空間,都容許在數據文件尾部進行Concurrent Insert;
b) concurrent_insert=1,當MyISAM 存儲引擎表數據文件中間不存在空閒空間的時候,能夠從文
件尾部進行Concurrent Insert;
c) concurrent_insert=0,不管MyISAM 存儲引擎的表數據文件的中間部分是否存在由於刪除數據
而留下的空閒空間,都不容許Concurrent Insert。
若是數據被刪除的可能性很小的時候,切對暫時性的浪費少許空間並非特別的在意的話,可將concurrent_insert 參數設置
爲2 ,數據文件中間留有空域空間,在浪費空間的時候,還會形成在查詢的時候須要讀取更多的數據,因此若是刪除量不是很小的話,
仍是建議將concurrent_insert 設置爲1 更爲合適。
3.縮短鎖定時間
惟一的辦法就是讓咱們的Query 執行時間儘量的短。
a) 盡兩減小大的複雜Query,將複雜Query 分拆成幾個小的Query 分佈進行;
b) 儘量的創建足夠高效的索引,讓數據檢索更迅速;
c) 儘可能讓MyISAM 存儲引擎的表只存放必要的信息,控制字段類型;
d) 利用合適的機會優化MyISAM 表數據文件;
二.Innodb 行鎖優化建議
要想合理利用Innodb 的行級鎖定,作到揚長避短,咱們必須作好如下工做:
a) 儘量讓全部的數據檢索都經過索引來完成,從而避免Innodb 由於沒法經過索引鍵加鎖而升級
爲表級鎖定;
b) 合理設計索引,讓Innodb 在索引鍵上面加鎖的時候儘量準確,儘量的縮小鎖定範圍,避免
形成沒必要要的鎖定而影響其餘Query 的執行;
c) 儘量減小基於範圍的數據檢索過濾條件,避免由於間隙鎖帶來的負面影響而鎖定了不應鎖定
的記錄;
d) 儘可能控制事務的大小,減小鎖定的資源量和鎖定時間長度;
e) 在業務環境容許的狀況下,儘可能使用較低級別的事務隔離,以減小MySQL 由於實現事務隔離級
別所帶來的附加成本;
經常使用的減小死鎖產生機率的的小建議:
a) 相似業務模塊中,儘量按照相同的訪問順序來訪問,防止產生死鎖;
b) 在同一個事務中,儘量作到一次鎖定所須要的全部資源,減小死鎖產生機率;
c) 對於很是容易產生死鎖的業務部分,能夠嘗試使用升級鎖定顆粒度,經過表級鎖定來減小死鎖
產生的機率;
三.系統鎖定爭用狀況查詢
MySQL 表級鎖定的爭用狀態變量:
mysql> show status like 'table%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Table_locks_immediate | 100 |
| Table_locks_waited | 0 |
+-----------------------+-------+
這兩個狀態變量記錄MySQL 內部表級鎖定的狀況,兩個變量說明以下:
● Table_locks_immediate:產生表級鎖定的次數;
● Table_locks_waited:出現表級鎖定爭用而發生等待的次數;
兩個狀態值都是從系統啓動後開始記錄,沒出現一次對應的事件則數量加1。若是這裏的Table_locks_waited
狀態值比較高,那麼說明系統中表級鎖定爭用現象比較嚴重,就須要進一步分析爲何會有較多的鎖定資源爭用了。
Innodb 記錄行級鎖定狀態的系統變量:
mysql> show status like 'innodb_row_lock%';
+-------------------------------+--------+
| Variable_name | Value |
+-------------------------------+--------+
| Innodb_row_lock_current_waits | 0 |
| Innodb_row_lock_time | 490578 |
| Innodb_row_lock_time_avg | 37736 |
| Innodb_row_lock_time_max | 121411 |
| Innodb_row_lock_waits | 13 |
+-------------------------------+--------+
● Innodb_row_lock_current_waits:當前正在等待鎖定的數量;
● Innodb_row_lock_time:從系統啓動到如今鎖定總時間長度;
● Innodb_row_lock_time_avg:每次等待所花平均時間;
● Innodb_row_lock_time_max:從系統啓動到如今等待最常的一次所花的時間;
● Innodb_row_lock_waits:系統啓動後到如今總共等待的次數;
比較重要的主要是Innodb_row_lock_time_avg( 等待平均時長),Innodb_row_lock_waits(等待總次數)
以及Innodb_row_lock_time(等待總時長)這三項。尤爲是當等待次數很高,並且每次等待時長也不小的時候,
咱們就須要分析系統中爲何會有如此多的等待,而後根據分析結果着手指定優化計劃。
此外,Innodb 提供的其即時狀態信息供咱們分析使用。能夠經過以下方法查看:
1. 經過建立Innodb Monitor 表來打開Innodb 的monitor 功能:
mysql> create table innodb_monitor(a int) engine=innodb;
Query OK, 0 rows affected (0.07 sec)
2. 而後經過使用「SHOW INNODB STATUS」查看細節信息
先建立monitor表實際上就是告訴Innodb 咱們開始要監控他的細節狀態了,而後Innodb 就會將比較詳細的事務
以及鎖定信息記錄進入MySQL 的error log 中,以便咱們後面作進一步分析使用。