MySQL 原理與優化之Update 優化

前言:

談到Update 語句大傢可能不會陌生,很多情況下我們都會使用它來更新table中的記錄。一般而言我們會使用innodb 的存儲引擎,innodb引擎是基於行鎖的,具體一點說是針對索引來加鎖的(保證鎖不能失效),並不是針對記錄加鎖,如果對於沒有建立索引的字段進行過濾操作,從而執行update 的話,會導致表鎖 。

今天就看看在使用innodb的時候如何使用update 語句。

已經存在course 表,其內容如下:

目前該表沒有加任何的索引,默認情況下id 是表的索引。

接著讓我們分別開啟兩個事務(兩個客戶端),分別執行下述指令。

開啟第一個事務:

begin;
update course set name = 'Java' where id = 1;

3

開啟另外一個事務

begin;
update course set name = 'Spark' where id = 4;

兩個事務都可以執行,然後再分別執行兩個事務的 commit 操作,就可以看到更新的結果。

兩個事務能夠並行執行的條件是id 是表course 的索引,可以由於update id 分別對應2 和4 ,隻是針對這兩行記錄進行加鎖。

接著讓我們看看另外一個例子,依舊是開啟兩個事務,但是where 條件選擇使用name ,而且name 沒有作為course 表的索引。

開啟一個事務:

begin;
update course set name = 'Vue.js' where name = 'PHP';

然後再執行另外一個事務

begin;
update course set name = 'SQLServer' where name = 'MySQL';

此時在執行第二個事務的update 語句的時候,會被阻塞。就是因為針對name 的過濾條件並不是course 的索引,此時的update 語句進行瞭鎖表的操作,必須等第一個事務commit之後,釋放掉表鎖,第二個事務才能繼續執行。

為瞭讓兩個事務能夠並行執行,我們將name 加入到course 的索引中去。

create index index_name on course(name);
show index from course;

接著再執行剛才的兩個事務,這兩個事務分別對不同的記錄進行更新,where 中的name條件不一樣的情況下,也不會出現鎖表的情況,這是因為將name 作為瞭course 的索引。

為瞭演示方便,這裡我們將更新的條件調整一下:

開啟一個事務:

begin;
update course set name = 'PHP' where name = 'Vue.js';

然後再執行另外一個事務

begin;
update course set name = 'MySQL' where name = 'SQLServer';

結果和我們預想的一樣,兩個事務可以並行執行,同時在commit之後能夠看到結果。

總結一下, 如果使用innodb存儲引擎,update 的時候存在where 條件的情況下,條件字段是索引的情況可以提升更新的效率,避免鎖表的情況發生。

到此這篇關於MySQL 原理與優化之Update 優化的文章就介紹到這瞭,更多相關MySQL Update 優化內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: