普通索引和唯一索引的選擇
業(yè)務(wù)場景一:是否將唯一字段設(shè)置為主鍵索引
數(shù)據(jù)中出現(xiàn)了一個(gè)字段保證是唯一的肚菠,是否高設(shè)計(jì)這個(gè)字段為主鍵呢?建議不使用,應(yīng)該創(chuàng)建一個(gè)遞增的唯一索引边涕。原因是在innodb中主鍵索引文件和數(shù)據(jù)文件是同一個(gè),利用遞增主鍵生成的索引樹占用內(nèi)存小褂微,主要表現(xiàn)在功蜓,自增主鍵自身就小,還有就是自增主鍵是遞增的宠蚂,生成的索引樹是緊湊的式撼,而唯一字段相對(duì)更大,并且是隨機(jī)的求厕,生成索引樹會(huì)造成也的分裂或者合并情況多著隆。
業(yè)務(wù)場景二:普通索引和唯一索引怎么選擇
分析:
- 查詢分析扰楼。對(duì)于唯一索引,當(dāng)我們查找到第一個(gè)滿足的時(shí)候就會(huì)返回美浦,對(duì)于普通索引查找到第一個(gè)滿足的情況還需要向下查找弦赖,直到查找到不滿足為止。這兩只之間的差距真的大嗎浦辨?其實(shí)不然蹬竖,因?yàn)閿?shù)據(jù)的讀取不是按行來讀取的,而是會(huì)讀取一頁的數(shù)據(jù)流酬,假如所有慢點(diǎn)的數(shù)據(jù)都在同一頁币厕,那么這兩者之間的差距微乎其微,但是如果是普通索引芽腾,可能會(huì)造成需要多一次磁盤IO的情況旦装,不過我覺得概率也是很低的。
- 操作分析摊滔。在普通索引中同辣,有一個(gè)change buffer 。這個(gè)change buffer是用來干什么的呢惭载?change buffer是為了減少磁盤的查詢IO的旱函。那為什么唯一索引沒有呢,因?yàn)槲ㄒ凰饕俏ㄒ坏拿杼希檎业臄?shù)據(jù)必須是在內(nèi)存中棒妨,change buffer無法作用。所以含长,先得出結(jié)論券腔,使用普通索引可能可以減少磁盤IO,而磁盤IO是數(shù)據(jù)庫最昂貴的操作。
change buffer的用途
既然change buffer是作用于普通索引拘泞,那么我們就來分析一下其對(duì)于普通索引的作用體現(xiàn)在哪里纷纫。
- insert/delete,當(dāng)插入的時(shí)候陪腌,假如數(shù)據(jù)在內(nèi)存中辱魁,則直接插入內(nèi)存中,記錄redo log诗鸭。假如數(shù)據(jù)也不在內(nèi)存中染簇,不需要讀取磁盤,在change buffer中記錄下來插入記錄强岸,記錄插入信息锻弓,記錄在change buffer 中插入信息。這兩條記錄記錄在redo log中蝌箍。
- update操作青灼,假如數(shù)據(jù)也在內(nèi)存中暴心,則直接修改,否則也是記錄在change buffer 中杂拨。
那么change buffer 中的記錄什么時(shí)候更新呢酷勺?當(dāng)下一次的查詢操作讀取到數(shù)據(jù)頁是,將會(huì)先執(zhí)行change buffer中的操作扳躬。
綜上脆诉,可以看出change buffe減少了磁盤IO操作。
宕機(jī)之后贷币,change buffer中的數(shù)據(jù)不會(huì)丟失嗎击胜?
其實(shí)change buffer中的數(shù)據(jù)也會(huì)保存在文件中,之后做merge操作役纹,merge操作怎么進(jìn)行呢偶摔?首先從磁盤中讀取數(shù)據(jù),然后將change buffer中的操作進(jìn)行促脉,可能是多個(gè)操作辰斋,之后再記錄redo log記錄chang buffer和數(shù)據(jù)的變更,此時(shí)內(nèi)存中的數(shù)據(jù)是最新的瘸味,但是磁盤中的數(shù)據(jù)還未更新宫仗,需要刷回磁盤。前面也提到了旁仿,在進(jìn)行操作的時(shí)候會(huì)記錄redo log藕夫,所以chang buffer的操作也是被記錄的,數(shù)據(jù)不會(huì)丟失枯冈。