高性能mysql

選取書中特別有代表性的點來講:

一:Mysql邏輯架構(gòu)

mysql的架構(gòu)解析:

當(dāng)一個sql請求從客戶端請求過來语御,先經(jīng)過連接池,連接池如果有空閑的線程,則可以直接用,如果沒有就新創(chuàng)建一個建立連接卢肃,如果是查詢類的sql,會先檢查是否命中緩存才顿,有緩存則直接返回緩存結(jié)果給客戶端莫湘,如果沒有命中緩存,則經(jīng)過解析器解析sql語法郑气,會解析出關(guān)鍵字和非關(guān)鍵字幅垮,解析sql是否合法,不合法會直接報錯終止線程竣贪,合法的話會進(jìn)入優(yōu)化器军洼,優(yōu)化器會為sql生成最優(yōu)的執(zhí)行計劃巩螃,例如選擇最合適的索引演怎,生成執(zhí)行計劃后調(diào)用存儲引擎的API,讓存儲引擎開始工作避乏,即到文件系統(tǒng)下進(jìn)行數(shù)據(jù)的讀取和寫入爷耀,并最終把結(jié)果返回給客戶端,如果是查詢類sql還會把結(jié)果緩存下來拍皮。

二:事務(wù)

事務(wù)的ACID特性

原子性(atomicity)歹叮,事務(wù)要么全部提交跑杭,要么全部回滾

一致性(consistency),數(shù)據(jù)庫總是從一個一致性的狀態(tài)轉(zhuǎn)換到另外一個一致性的狀態(tài)

隔離性(isolation)咆耿,通常一個事務(wù)所做的修改在最終提交以前德谅,對其他事務(wù)是不可見的(也有例外,隔離性最低等級未提交讀對其他事務(wù)是可見的)

持久性(durability)萨螺,一旦事務(wù)提交窄做,則其所做的修改就會永久保存到數(shù)據(jù)庫中。

注:實際應(yīng)用中慰技,要實現(xiàn)ACID全部特性非常難椭盏,一個兼容ACID的數(shù)據(jù)庫系統(tǒng),需要做很多復(fù)雜但可能用戶并沒有覺察到的工作吻商,才能確保ACID的實現(xiàn)掏颊。平時根據(jù)你自己業(yè)務(wù)是否需要事務(wù),來選擇合適的存儲引擎艾帐。innodb支持事務(wù)乌叶,myisam不支持事務(wù),但大部分場景都是用innodb的柒爸,mysql5.5以后的版本都默認(rèn)innodb引擎

隔離級別

ACID特性中的隔離性分四個等級枉昏,由低到高(級別越高,安全性越高揍鸟,級別越低兄裂,并發(fā)能力越好,性能開銷低):

READ UNCOMMITTED(未提交讀)

將事務(wù)設(shè)置為未提交讀等級

事務(wù)A

事務(wù)B

結(jié)論:事務(wù)B更新了一條記錄阳藻,但是沒有提交晰奖,此時事務(wù)A可以查詢出未提交記錄,造成臟讀現(xiàn)象腥泥。未提交讀是最低的隔離級別匾南,很少應(yīng)用到

READ COMMITTED(提交讀)

將事務(wù)設(shè)置為提交讀等級

事務(wù)A

事務(wù)B

結(jié)論:已提交讀隔離級別解決了臟讀的問題,但是出現(xiàn)了不可重復(fù)讀的問題蛔外,即事務(wù)B更新了數(shù)據(jù)前后蛆楞,事務(wù)A在兩次查詢的數(shù)據(jù)不一致

REPEATABLE READ(可重復(fù)讀)

實驗略〖醒幔可重復(fù)讀隔離級別解決了臟讀和不可重復(fù)讀問題豹爹,它只允許讀取已提交記錄,而且在一個事務(wù)兩次讀取一個記錄期間矛纹,其他事務(wù)部的更新該記錄臂聋。但該事務(wù)不要求與其他事務(wù)可串行化。例如,當(dāng)一個事務(wù)可以找到由一個已提交事務(wù)更新的記錄孩等,但是可能產(chǎn)生幻讀問題艾君。幻讀就是事務(wù)A提交事務(wù)后再次查詢肄方,如果其他事務(wù)插入新行冰垄,那么會出現(xiàn)新行產(chǎn)生幻讀問題。(注意是可能权她,因為數(shù)據(jù)庫對隔離級別的實現(xiàn)有所差別)播演。mysql是默認(rèn)這種隔離級別。

SERIALIZABLE(可串行化)

實驗略伴奥。它通過強(qiáng)制事務(wù)串行執(zhí)行写烤,比如在事務(wù)A執(zhí)行過程中會禁止其他事務(wù)插入數(shù)據(jù),避免了前面說的幻讀的問題拾徙。SERIALIZABLE會在讀取的每一行數(shù)據(jù)上都加鎖洲炊,所以可能導(dǎo)致大量的超時和鎖爭用的問題。實際應(yīng)用中也很少用到這個隔離級別尼啡,只有在非常需要確保數(shù)據(jù)的一致性而且可以接受沒有并發(fā)的情況下暂衡,才考慮采用該級別。

事務(wù)死鎖

死鎖是指兩個或者多個事務(wù)在同一資源上相互占用崖瞭,并請求鎖定對方占用的資源狂巢,從而導(dǎo)致惡性循環(huán)的現(xiàn)象。當(dāng)多個事務(wù)試圖以不同的順序鎖定資源時书聚,就可能會產(chǎn)生死鎖唧领。多個事務(wù)同時鎖定同一個資源時,也會產(chǎn)生死鎖雌续。舉例:事務(wù)A先更新id=1再更新id=2,事務(wù)B同時先更新id=2再更新id=1斩个,兩個事務(wù)互相占有對方資源,然后請求對方資源驯杜,產(chǎn)生死鎖受啥。

三、數(shù)據(jù)類型

數(shù)據(jù)類型選擇

更小的通常更好鸽心。

應(yīng)該盡量使用可以正確存儲數(shù)據(jù)的最小數(shù)據(jù)類型滚局。例如能用smallint盡量不用int,因為更小的數(shù)據(jù)類型通常更快顽频,它們占用更少的磁盤藤肢、內(nèi)存和CPU緩存,并且處理時需要的CPU周期也更少冲九。

簡單就好

簡單數(shù)據(jù)類型的操作通常需要更少的CPU周期谤草,例如不用字符串,而是用更簡單的整型存儲IP地址

盡量避免NULL

當(dāng)可為NULL的列被索引時莺奸,每個索引記錄需要一個額外的字節(jié)丑孩,因此可為NULL的列會使用更多的存儲空間。

幾種重要的數(shù)據(jù)類型

整型

整型取值范圍

MySQL可以為整數(shù)類型指定寬度灭贷,例如INT(11)温学,對于存儲和計算來說,INT(1)和INT(5)是相同的甚疟,區(qū)別在于字段類型加入 zerofill 參數(shù)后仗岖,值1234在INT(1)顯示為1234,在INT(5)顯示為01234览妖,即不夠?qū)挾仍谇懊嫜a(bǔ)0

實數(shù)

FLOAT和DOUBLE類型支持使用標(biāo)準(zhǔn)的浮點運(yùn)算進(jìn)行近似計算轧拄。

DECIMAL類型用于存儲精確的小數(shù)。

浮點類型由于取值范圍的影響讽膏,會導(dǎo)致實際保存與我們期望的不符合檩电,F(xiàn)LOAT類型整數(shù)超過6位就會有誤差,所以金錢相關(guān)的盡量用DECIMAL類型

DECIMAL因為需要額外的空間和計算開銷府树,所以應(yīng)該盡量只在對小數(shù)進(jìn)行精確計算時才使用DECIMAL俐末。但在數(shù)據(jù)量比較大的時候,可以考慮使用BIGINT代替DECIMAL奄侠,將需要存儲的貨幣單位根據(jù)小數(shù)的位數(shù)乘以相應(yīng)的倍數(shù)即可

字符串類型

VARCHAR類型

優(yōu)點:用于存儲可變長字符串卓箫,越短的字符串使用越少的空間,VARCHAR節(jié)省了存儲空間垄潮,所以對性能也有幫助烹卒。

缺點:VARCHAR需要使用1或2個額外字節(jié)記錄字符串的長度,由于行是變長的弯洗,在UPDATE時可能使行變得比原來更長甫题,這就導(dǎo)致需要做額外的工作,會產(chǎn)生碎片

使用場景:字符串列的最大長度比平均長度大很多涂召;列的更新很少坠非,所以碎片不是問題;使用了像UTF-8這樣復(fù)雜的字符集果正,每個字符都使用不同的字節(jié)數(shù)進(jìn)行存儲炎码。

CHAR類型

使用場景:CHAR非常適合存儲密碼的MD5值,因為這是一個定長的值秋泳。對于經(jīng)常變更的數(shù)據(jù)潦闲,CHAR也比VARCHAR更好,因為定長的CHAR類型不容易產(chǎn)生碎片迫皱。對于非常短的列歉闰,CHAR比VARCHAR在存儲空間上也更有效率辖众。例如用CHAR(1)來存儲只有Y和N的值,如果采用單字節(jié)字符集(5)只需要一個字節(jié)和敬,但是VARCHAR(1)卻需要兩個字節(jié)凹炸,因為還有一個記錄長度的額外字節(jié)。

日期和時間類型

DATETIME和TIMESTAMP的比較

TIMESTAMP比DATETIME占空間小昼弟。DATETIME是使用8個字節(jié)的存儲空間啤它,TIMESTAMP是使用4個字節(jié)的存儲空間。

TIMESTAMP的范圍比DATETIME小得多舱痘。DATETIME能保存大范圍的值变骡,從1001年到9999年,精度為秒芭逝。TIMESTAMP只能表示從1970年到2038年塌碌,但這種范圍已經(jīng)可以滿足大部分日常使用。

TIMESTAMP顯示方式比DATETIME更靈活旬盯。DATETIME存什么顯示什么誊爹,TIMESTAMP存儲的是時間戳,顯示mysql所在時區(qū)的時間瓢捉,如果儲存時的時區(qū)和檢索時的時區(qū)不一樣频丘,那么拿出來的數(shù)據(jù)也不一樣。

范式反范式的優(yōu)點和缺點

范式的優(yōu)點

范式化的更新操作通常比反范式化要快泡态。

當(dāng)數(shù)據(jù)較好地范式化時搂漠,就只有很少或者沒有重復(fù)數(shù)據(jù),所以只需要修改更少的數(shù)據(jù)某弦。

范式化的表通常更小桐汤,可以更好地放在內(nèi)存里,所以執(zhí)行操作會更快靶壮。

很少有多余的數(shù)據(jù)意味著檢索列表數(shù)據(jù)時更少需要DISTINCT或者GROUP BY語句怔毛。

范式的缺點

通常需要關(guān)聯(lián)。稍微復(fù)雜一些的查詢語句在符合范式的schema上都可能需要至少一次關(guān)聯(lián)腾降,也許更多拣度。這不但代價昂貴,也可能使一些索引策略無效

反范式的優(yōu)點

反范式化的schema因為所有數(shù)據(jù)都在一張表中螃壤,可以很好地避免關(guān)聯(lián)抗果。

如果不需要關(guān)聯(lián)表,則對大部分查詢最差的情況——即使表沒有使用索引——是全表掃描奸晴。當(dāng)數(shù)據(jù)比內(nèi)存大時這可能比關(guān)聯(lián)要快得多冤馏,因為這樣避免了隨機(jī)I/O(14)。

單獨(dú)的表也能使用更有效的索引策略寄啼。

反范式的缺點

當(dāng)MySQL需要掃描表字段的索引逮光,對于每一行找到的數(shù)據(jù)代箭,將需要到表里檢查數(shù)據(jù)是不是符合條件。如果只有一小部分符合條件是效率低下

通過是范式化和反范式化兩者混用

四涕刚、索引

索引大大減少了服務(wù)器需要掃描的數(shù)據(jù)量嗡综。

索引可以幫助服務(wù)器避免排序和臨時表。

索引可以將隨機(jī)I/O變?yōu)轫樞騃/O副女。

B+tree索引

B-tree是從最簡單的二叉樹進(jìn)化到平衡二叉樹蛤高,再進(jìn)化到多路平衡查找樹蚣旱,即B-tree碑幅,最后進(jìn)化到B-tree改進(jìn)版B+tree,innodb采用的就是B+tree

B-tree的非葉子節(jié)點只存儲鍵值信息塞绿,這樣節(jié)省了磁盤塊的空間沟涨,可以實現(xiàn)更多路,使樹的高度更小异吻,加快查找速度

所有葉子節(jié)點之間都有一個鏈指針裹赴。

數(shù)據(jù)記錄都存放在葉子節(jié)點中

索引命中情況

全值匹配

全值匹配指的是和索引中的所有列進(jìn)行匹配

匹配最左前綴

只使用索引的第一列

匹配列前綴

只匹配索引列的值的開頭部分

匹配范圍值

只使用了索引的第一列進(jìn)行范圍查找

精確匹配某一列并范圍匹配另外一列

索引命中限制

如果不是按照索引的最左列開始查找,則無法使用索引

不能跳過索引中的列

如果查詢中有某個列的范圍查詢诀浪,則其右邊所有列都無法使用索引優(yōu)化查找

高性能的索引策略

獨(dú)立的列棋返,索引列不能是表達(dá)式的一部分,也不能是函數(shù)的參數(shù)雷猪。WHERE actor_id + 1 = 5;是一個表達(dá)式

選擇合適的索引列順序

以下面的查詢?yōu)槔?/p>

是應(yīng)該創(chuàng)建一個(staff_id睛竣,customer_id)索引還是應(yīng)該顛倒一下順序?如下所示,

根據(jù)經(jīng)驗法則求摇,應(yīng)該將索引列customer_id放到前面射沟,因為對應(yīng)條件值的customer_id數(shù)量更小。

聚簇索引

下圖展示了聚簇索引中的記錄是如何存放的与境。注意到验夯,葉子頁包含了行的全部數(shù)據(jù),但是節(jié)點頁只包含了索引列摔刁。

如果沒有定義主鍵挥转,InnoDB會選擇一個唯一的非空索引代替。如果沒有這樣的索引共屈,InnoDB會隱式定義一個主鍵來作為聚簇索引扁位。InnoDB只聚集在同一個頁面中的記錄。包含相鄰鍵值的頁面可能會相距甚遠(yuǎn)趁俊。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末域仇,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子寺擂,更是在濱河造成了極大的恐慌暇务,老刑警劉巖泼掠,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異垦细,居然都是意外死亡择镇,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進(jìn)店門括改,熙熙樓的掌柜王于貴愁眉苦臉地迎上來腻豌,“玉大人,你說我怎么就攤上這事嘱能×呙罚” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵惹骂,是天一觀的道長苏携。 經(jīng)常有香客問我,道長对粪,這世上最難降的妖魔是什么右冻? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮著拭,結(jié)果婚禮上纱扭,老公的妹妹穿的比我還像新娘。我一直安慰自己儡遮,他們只是感情好乳蛾,可當(dāng)我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著屡久,像睡著了一般。 火紅的嫁衣襯著肌膚如雪爱榔。 梳的紋絲不亂的頭發(fā)上被环,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天,我揣著相機(jī)與錄音详幽,去河邊找鬼筛欢。 笑死,一個胖子當(dāng)著我的面吹牛唇聘,可吹牛的內(nèi)容都是我干的版姑。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼迟郎,長吁一口氣:“原來是場噩夢啊……” “哼剥险!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起宪肖,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤表制,失蹤者是張志新(化名)和其女友劉穎健爬,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體么介,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡娜遵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了壤短。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片设拟。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖久脯,靈堂內(nèi)的尸體忽然破棺而出纳胧,到底是詐尸還是另有隱情,我是刑警寧澤桶现,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布躲雅,位于F島的核電站鼎姊,受9級特大地震影響骡和,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜相寇,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一慰于、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧唤衫,春花似錦婆赠、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至赃承,卻和暖如春妙黍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背瞧剖。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工拭嫁, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人抓于。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓做粤,卻偏偏與公主長得像,于是被迫代替她去往敵國和親捉撮。 傳聞我的和親對象是個殘疾皇子怕品,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,724評論 2 354