第一時間獲取技術乾貨和業界資訊!面試
前面我推薦了極客時間的 Java 高併發課程,不少人根據這篇文章《!(a)(b)2019 Java 高併發學習路線圖和必會的 50 道面試題!》的介紹買了課程,我但願你們可以認真的看!別把錢浪費了!編程
今天,我來講另一個面試題。爲何推薦 MySQL 的 update 語句中 where 條件要有主鍵?併發
看到這個問題的朋友,我相信很多人有疑問,我 where 不加主鍵還不能更新了?框架
不是的,能更新,也能使用。可是我不建議大家這樣作。由於咱們大多數人使用 MySQL 都使用的是 innodb 存儲引擎,它是支持事務的。若是你的 where 條件不加主鍵,那麼 innodb 的行級鎖就可能變成表級鎖。若是升級爲表級鎖,那麼併發性就將大打折扣了。高併發
以前也有網友在個人文章裏評論說,行鎖升級爲表鎖與事務的隔離級別有關,由於事務的隔離性是靠加鎖來實現的,而加鎖不當勢必會影響併發。學習
不同的鎖,支持的併發也是不同的。而最終加什麼樣的鎖,與索引也有莫大的關係,所以,能夠說採用什麼樣的索引決定了支持多少併發。測試
經常使用的索引有三類:主鍵、惟一索引、普通索引。主鍵我就再也不細說,自帶最高效的索引屬性;惟一索引指的是該屬性值重複率爲 0,通常可做爲業務主鍵,例如訂單號;普通索引 與前者不一樣的是,屬性值的重複率大於 0,不能做爲惟一指定條件,例如購買用戶的姓名。今天我主要想說的是「普通索引對併發的影響」。人工智能
沒有索引的狀況,我就不說了,那對併發來講確定是災難,死鎖估計是常有的事。spa
爲何我推薦 update 中 where 條件加入主鍵呢?3d
由於主鍵是惟一索引,你用其餘惟一索引也能夠,可是通常的表,可能只有主鍵纔是惟一的。因此,我建議你更新的時候,記住加上主鍵就好了。
你只須要記住主鍵和惟一索引是行鎖,其餘索引並不必定是行鎖,極可能是表鎖。這樣,死鎖的機率就很是的高,併發也就隨之降低。
下面咱們經過一個簡單的例子來看一下,普通索引的狀況。
相關建表語句,索引,和數據以下所示:
而後取消事務自動提交 set autocommit = off;
當咱們表裏面建立時間重複率比較高的時候。分別開啓兩個窗口,兩個事務。
爲了演示,你能夠把數據量加多點,好比 03-01 和 03-02 的數據各 10 萬條。
依次執行兩個窗口中的 SQL,你會發現,其中一個窗口中的更新失敗了。提示:
看似這兩個事務不互相干,可是在其中一個事務中更新本身鎖定的數據失敗後,應該能說明在此時引起了表鎖。這是在非主鍵索引或者說是惟一索引,而且索引數據重複量比較高的狀況下,你的更新發生量表鎖。併發能力就會大大降低!
大家能夠試一下,若是此時使用主鍵或惟一索引會不會這樣。
在咱們的電商系統中,這樣的代碼並很多。在一些熱門商品和秒殺、優惠、打折等活動中常常會發生一些莫名其妙的異常,致使用戶體驗大打折扣。
上面的測試數據,你把它們所有刪除,而後再新增一些數據,這些數據中在 create_time 重複率爲 0 的狀況下,你會發現兩個事務就都能成功了。這說明它們這時用的應該是行級鎖,效率更高。
以上,測試說明在更新數據時,儘可能使用主鍵或惟一索引。可是惟一索引並很多每一個表都有的,而主鍵必須是每一個表都必須有的。因此,我建議大家在更新數據時,都帶上主鍵!
10T技術資源大放送!包括但不限於:C/C++,Linux,Python,Java,PHP,人工智能,GO等等。在公衆號內回覆對應關鍵字或框架名字,便可免費獲取!!