真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

InnoDB為什么update要盡量使用索引

這篇文章將為大家詳細講解有關(guān)InnoDB為什么update要盡量使用索引,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。          

成都創(chuàng)新互聯(lián)公司專業(yè)為企業(yè)提供吉陽網(wǎng)站建設(shè)、吉陽做網(wǎng)站、吉陽網(wǎng)站設(shè)計、吉陽網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計與制作、吉陽企業(yè)網(wǎng)站模板建站服務(wù),十余年吉陽做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡(luò)服務(wù)。

從一個問題展開討論

 問題:innodb行級鎖是通過鎖索引記錄實現(xiàn)的,如果update語句的where列沒建索引,即使只update一條記錄也會鎖住整張表嗎?

答案是肯定的。 我從當前本地數(shù)據(jù)庫中找出一張建立自增主鍵的表來演示。打開兩個終端窗口,用于驗證當a端執(zhí)行update語句時b端是否會被鎖住。首先表的結(jié)構(gòu)如下圖所示。 

InnoDB為什么update要盡量使用索引

測試表stu_score中,id是主鍵索引,其它的列都是沒有建立索引的?,F(xiàn)在要測試一下當執(zhí)行update語句時,如果where沒有使用索引,那么是整張表都被鎖住呢,還是只會鎖住滿足條件的行呢?注意記得不要忘記開啟一個事務(wù)。 

InnoDB為什么update要盡量使用索引

從上面的截圖中可以看出,當在A端執(zhí)行where name=“wujiuye”的update語句時,雖然滿足name=“wujiuye”的記錄只有一條,但是innodb卻將整張表都鎖住了,在A端未將事務(wù)提交之前B端執(zhí)行更新其它行的update語句被阻塞了。 

接著來看一個使用索引的update示例 

InnoDB為什么update要盡量使用索引

如上面截圖所示,在a端由于update語句只對id=1008的這條記錄做修改,id是主鍵,所以innodb只將id=1008的這行記錄加鎖了,所以在b端同樣只對id=1007的行做修改,所以也只會鎖住id=1007這行記錄。

你也可以驗證一下是否加了行鎖,在a、b端不同事務(wù)間對同一行記錄執(zhí)行 update語句。 

InnoDB為什么update要盡量使用索引

很明顯,a端先執(zhí)行了update where id=1008,所以先獲取了id=1008這行記錄的鎖,然后再到b端執(zhí)行update where id=1008的時候由于鎖已經(jīng)被其它事務(wù)占用了,只能進入等待狀態(tài)。當a端提交事務(wù)時b端才會獲得鎖繼續(xù)執(zhí)行,或者b端等待超時了(事務(wù)默認鎖超時50s)直接執(zhí)行失敗,事務(wù)進行回滾。 

如果你在b端執(zhí)行where name=“wujiuye”的update語句就會進入阻塞了,因為它需要獲得表鎖,會將整個表鎖住,不信可以看下面的實驗結(jié)果。 

InnoDB為什么update要盡量使用索引

使用行鎖會出現(xiàn)死鎖情況,來看個例子。 

InnoDB為什么update要盡量使用索引

在a端先對id=1008這行記錄做update操作,獲得了id=1008的行鎖,(在需要的時候才會加鎖,但是只有事務(wù)提交的時候才會釋放鎖,這是二階段鎖的概念。)然后到b端對id=1007這行記錄做update操作,獲得了id=1007這行記錄的行鎖,這時候a事務(wù)持有id=1008的行鎖,b事務(wù)持有id=1007的行鎖,也都沒有什么問題,但是當a端繼續(xù)執(zhí)行對b端已經(jīng)加鎖的記錄執(zhí)行寫操作時,就會進行阻塞狀態(tài),而如果此時b端也想對a端加鎖的記錄執(zhí)行寫操作,那么就會出現(xiàn)死鎖狀態(tài)了。

不過經(jīng)過上面的實驗驗證,innodb已經(jīng)默認幫我們排除死鎖情況了,所以出現(xiàn)當我在b端執(zhí)行最后一句update的時候就立馬報錯了,提示:deadlock found when trying to get lock;嘗試獲取鎖時發(fā)現(xiàn)死鎖。 

               總結(jié)

兩階段鎖協(xié)議:在 InnoDB 事務(wù)中,行鎖是在需要的時候才加上的,但并不是不需要了就立刻釋放,而是要等到事務(wù)結(jié)束時才釋放。 

了解這個對我們有什么幫助?在并發(fā)情況下,對于那種多用戶共享操作的記錄是不是加鎖的時間越少越好?比如,購買一件商品,同一件商品是不是可以有多個用戶同時購買,這樣就是多個事務(wù)中訪問了同一商品表的同一行記錄,而購買付款是不是每個事務(wù)中只對當前用戶對應(yīng)的記錄做修改,所以怎么優(yōu)化呢?記住,只有在需要的時候才會加鎖,所以對商品記錄加行鎖是在減庫存的時候進行加鎖的,為了加鎖時間少,是不是可以先執(zhí)行用戶的扣款操作,添加訂單記錄操作,最后再執(zhí)行減庫存操作,然后提交事務(wù),在準備提交事務(wù)時再執(zhí)行減庫存操作,這樣就是減少加鎖時間,也能提交并發(fā)效率。 

如果上面的例子看不懂沒關(guān)系,我在網(wǎng)上找了一個例子。 假設(shè)你負責(zé)實現(xiàn)一個電影票在線交易業(yè)務(wù),顧客 A 要在影院 B 購買電影票。我們簡化一點,這個業(yè)務(wù)需要涉及到以下操作: 

(1)從顧客 A 賬戶余額中扣除電影票價; 

(2)給影院 B 的賬戶余額增加這張電影票價; 

(3)記錄一條交易日志。 

也就是說,要完成這個交易,我們需要 update 兩條記錄,并 insert 一條記錄。當然,為了保證交易的原子性,我們要把這三個操作放在一個事務(wù)中。

那么,你會怎樣安排這三個語句在事務(wù)中的順序呢?試想如果同時有另外一個顧客 C 要在影院 B 買票,那么這兩個事務(wù)沖突的部分就是語句 2 了。因為它們要更新同一個影院賬戶的余額,需要修改同一行數(shù)據(jù)。 

根據(jù)兩階段鎖協(xié)議,不論你怎樣安排語句順序,所有的操作需要的行鎖都是在事務(wù)提交的時候才釋放的。所以,如果你把語句 2 安排在最后,比如按照 3、1、2 這樣的順序,那么影院賬戶余額這一行的鎖時間就最少。這就最大程度地減少了事務(wù)之間的鎖等待,提升了并發(fā)度。

關(guān)于InnoDB為什么update要盡量使用索引就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。


新聞標題:InnoDB為什么update要盡量使用索引
分享地址:http://weahome.cn/article/ggojgc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部