華為程序員面試題:調(diào)整SQL的執(zhí)行順序,對(duì)性能有沒(méi)有影響
每年的3,4月份都是求職的高峰期,今天我們來(lái)分享一個(gè)經(jīng)典的面試題,這個(gè)題目是來(lái)自一位粉絲最近參與的一次華為面試后臺(tái)工程師面試。
我們有一個(gè)交易系統(tǒng),每當(dāng)發(fā)生一次交易操作的時(shí)候,會(huì)發(fā)生下面幾個(gè)事情,增加一條交易記錄,買家的金額減少X元,賣家的金額增加X(jué)元。很顯然,為了保證數(shù)據(jù)的一致性,我們需要在事務(wù)下完成這三個(gè)操作,那么,這3條sql的執(zhí)行順序,對(duì)系統(tǒng)的系能有沒(méi)有什么影響呢?
大家都知道,在數(shù)據(jù)庫(kù)中,如果有多個(gè)不同的任務(wù)同時(shí)對(duì)同一行數(shù)據(jù)有更新,那么就可能會(huì)出現(xiàn)并發(fā)問(wèn)題。為了解決這個(gè)問(wèn)題,Mysql有著復(fù)雜的鎖的機(jī)制,一般情況下,我們這種只更新某一行的數(shù)據(jù)通常使用的的是Mysql的行鎖。同時(shí)在所有的數(shù)據(jù)庫(kù)操作中,我們必須保證一個(gè)狀態(tài)到另外一個(gè)狀態(tài)的數(shù)據(jù)一致性,也就是事務(wù),那么Mysql的事務(wù)跟鎖有什么關(guān)系呢?
Mysql的行鎖,是在需要的時(shí)候申請(qǐng),但并不是立馬釋放,而是等到事務(wù)結(jié)束后才釋放,我們稱之為二階段協(xié)議?;谶@樣的一種設(shè)定,如果我們要提高系統(tǒng)的整體性能,就要讓等到鎖的時(shí)間越少越好,也就是并發(fā)越高的修改,放到越后面,這樣子,就能夠在處理完當(dāng)前數(shù)據(jù)庫(kù)操作之后,盡快地提交事務(wù),并釋放鎖,交給下一個(gè)任務(wù)。
在上述例子中,增加一條交易記錄,一般都是追加的操作,不需要加鎖,而給買家的金額減X元,通常,一個(gè)買家同一時(shí)間內(nèi),都不會(huì)有并發(fā),即使有(例如手機(jī),APP同時(shí)下單付款等)那也是非常小的概率事件,但是對(duì)于賣家就不一定了,特別是一些爆品,賣家設(shè)置可能在1秒鐘內(nèi)完成數(shù)百次甚至上千次并發(fā)。所以,我們應(yīng)該把賣家金額的變更放到最后,那樣能夠很大程度地提升系統(tǒng)的性能。