mysql存儲引擎innodb行鎖和表鎖

Mysql的InnoDB存儲引擎支持事務,默認是行鎖。因爲這個特性,所以數據庫支持高併發,但是如果InnoDB更新數據的時候不是行鎖,而是表鎖的話,那麼其併發性會大打折扣,而且也可能導致你的程序出錯。

而導致行鎖變爲表鎖的情況之一就是:

SQL的更新(update)或者刪除(delete)語句中未使用到索引,導致在InnoDB在對數據進行相應操作的時候必須把整個表鎖起來進行檢索(表鎖)。而如果使用了索引的話,InnoDB只會通過索引條件檢索數據,而只鎖住索引對應的行(行鎖)。

下面記錄一下我遇到的問題:

描述:

系統中有一個實時的定時任務,當有條件觸發的時候,會更新對應的表,就先叫其爲A表;
但是同時有一個任務有時候會對A表有寫操作,因此當進行測試的時候,有時候會不固定的出“Lock wait timeout exceeded”的錯誤。
  當出現這個問題的時候,從很多的地方進行了分析,然後都無法得到正確的解決方案(因爲描述1模塊不是我寫的,所以沒有去查看更新表的代碼操作)

導致原因:

在描述1中定時任務更新表A的時候,更新條件中沒有使用索引,導致當進行定時任務更新表的時候形成了表鎖。然後因爲表A數據量比較大,檢索較慢,然後導致了描述2中對錶A的寫操作的等鎖超時。

最常見的索引:

主鍵:衆所周知,自帶最高效的索引屬性,自動創建,聚簇索引
唯一索引:屬性值重複率爲0,可以作爲業務主鍵
普通索引:屬性值重複率大於0,不能作爲唯一指定條件
  注意:對於普通索引,當“重複率”低時,甚至接近主鍵或者唯一索引的效果時,依然是行鎖;但是如果“重複率”高時,Mysql不會把這個普通索引當做索引,即會造成一個沒有索引的SQL,從而形成表鎖。重複率高的情況下且數據量較小的情況下,可以不建立索引。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章