天天看點

MySQL 原理與優化:Update 優化

MySQL 原理與優化:Update 優化

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

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

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

MySQL 原理與優化:Update 優化

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

接着讓我們分别開啟兩個事務(兩個用戶端),分别執行下述指令。

開啟第一個事務

begin;

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

MySQL 原理與優化:Update 優化

開啟另外一個事務

begin;

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

MySQL 原理與優化:Update 優化

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

MySQL 原理與優化:Update 優化

兩個事務能夠并行執行的條件是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之後,釋放掉表鎖,第二個事務才能繼續執行。

MySQL 原理與優化:Update 優化

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

create index index_name on course(name);

show index from course;

MySQL 原理與優化:Update 優化

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

為了示範友善,這裡我們将更新的條件調整一下:

開啟一個事務:

begin;

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

然後再執行另外一個事務

begin;

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

繼續閱讀