更新時(shí)間:2020-02-13 10:46:56 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽2876次
為什么用自增列作為主鍵
1、如果我們定義了主鍵(PRIMARYKEY),那么InnoDB會(huì)選擇主鍵作為聚集索引。
如果沒(méi)有顯式定義主鍵,則InnoDB會(huì)選擇第一個(gè)不包含有NULL值的唯一索引作為主鍵索引。
如果也沒(méi)有這樣的唯一索引,則InnoDB會(huì)選擇內(nèi)置6字節(jié)長(zhǎng)的ROWID作為隱含的聚集索引(ROWID隨著行記錄的寫(xiě)入而主鍵遞增,這個(gè)ROWID不像ORACLE的ROWID那樣可引用,是隱含的)。
2、數(shù)據(jù)記錄本身被存于主索引(一顆B+Tree)的葉子節(jié)點(diǎn)上,這就要求同一個(gè)葉子節(jié)點(diǎn)內(nèi)(大小為一個(gè)內(nèi)存頁(yè)或磁盤(pán)頁(yè))的各條數(shù)據(jù)記錄按主鍵順序存放
因此每當(dāng)有一條新的記錄插入時(shí),MySQL會(huì)根據(jù)其主鍵將其插入適當(dāng)?shù)墓?jié)點(diǎn)和位置,如果頁(yè)面達(dá)到裝載因子(InnoDB默認(rèn)為15/16),則開(kāi)辟一個(gè)新的頁(yè)(節(jié)點(diǎn))
3、如果表使用自增主鍵,那么每次插入新的記錄,記錄就會(huì)順序添加到當(dāng)前索引節(jié)點(diǎn)的后續(xù)位置,當(dāng)一頁(yè)寫(xiě)滿,就會(huì)自動(dòng)開(kāi)辟一個(gè)新的頁(yè)
4、如果使用非自增主鍵(如果身份證號(hào)或?qū)W號(hào)等),由于每次插入主鍵的值近似于隨機(jī),因此每次新紀(jì)錄都要被插到現(xiàn)有索引頁(yè)得中間某個(gè)位置
此時(shí)MySQL不得不為了將新記錄插到合適位置而移動(dòng)數(shù)據(jù),甚至目標(biāo)頁(yè)面可能已經(jīng)被回寫(xiě)到磁盤(pán)上而從緩存中清掉,此時(shí)又要從磁盤(pán)上讀回來(lái),這增加了很多開(kāi)銷
同時(shí)頻繁的移動(dòng)、分頁(yè)操作造成了大量的碎片,得到了不夠緊湊的索引結(jié)構(gòu),后續(xù)不得不通過(guò)OPTIMIZETABLE來(lái)重建表并優(yōu)化填充頁(yè)面。
為什么使用數(shù)據(jù)索引能提高效率
數(shù)據(jù)索引的存儲(chǔ)是有序的
在有序的情況下,通過(guò)索引查詢一個(gè)數(shù)據(jù)是無(wú)需遍歷索引記錄的
極端情況下,數(shù)據(jù)索引的查詢效率為二分法查詢效率,趨近于log2(N)
B+樹(shù)索引和哈希索引的區(qū)別
B+樹(shù)是一個(gè)平衡的多叉樹(shù),從根節(jié)點(diǎn)到每個(gè)葉子節(jié)點(diǎn)的高度差值不超過(guò)1,而且同層級(jí)的節(jié)點(diǎn)間有指針相互鏈接,是有序的,如下圖:
哈希索引就是采用一定的哈希算法,把鍵值換算成新的哈希值,檢索時(shí)不需要類似B+樹(shù)那樣從根節(jié)點(diǎn)到葉子節(jié)點(diǎn)逐級(jí)查找,只需一次哈希算法即可,是無(wú)序的。
哈希索引的優(yōu)勢(shì):
等值查詢,哈希索引具有絕對(duì)優(yōu)勢(shì)(前提是:沒(méi)有大量重復(fù)鍵值,如果大量重復(fù)鍵值時(shí),哈希索引的效率很低,因?yàn)榇嬖谒^的哈希碰撞問(wèn)題。)
為什么說(shuō)B+比B樹(shù)更適合實(shí)際應(yīng)用中操作系統(tǒng)的文件索引和數(shù)據(jù)庫(kù)索引?
1、B+的磁盤(pán)讀寫(xiě)代價(jià)更低。
B+的內(nèi)部結(jié)點(diǎn)并沒(méi)有指向關(guān)鍵字具體信息的指針,因此其內(nèi)部結(jié)點(diǎn)相對(duì)B樹(shù)更小。
如果把所有同一內(nèi)部結(jié)點(diǎn)的關(guān)鍵字存放在同一盤(pán)塊中,那么盤(pán)塊所能容納的關(guān)鍵字?jǐn)?shù)量也越多。一次性讀入內(nèi)存中的需要查找的關(guān)鍵字也就越多。相對(duì)來(lái)說(shuō)IO讀寫(xiě)次數(shù)也就降低了。
2、B+-tree的查詢效率更加穩(wěn)定。
由于非終結(jié)點(diǎn)并不是最終指向文件內(nèi)容的結(jié)點(diǎn),而只是葉子結(jié)點(diǎn)中關(guān)鍵字的索引。所以任何關(guān)鍵字的查找必須走一條從根結(jié)點(diǎn)到葉子結(jié)點(diǎn)的路。所有關(guān)鍵字查詢的路徑長(zhǎng)度相同,導(dǎo)致每一個(gè)數(shù)據(jù)的查詢效率相當(dāng)。
MySQL聯(lián)合索引
1、聯(lián)合索引是兩個(gè)或更多個(gè)列上的索引。
對(duì)于聯(lián)合索引:Mysql從左到右的使用索引中的字段,一個(gè)查詢可以只使用索引中的一部份,但只能是最左側(cè)部分。
例如索引是keyindex(a,b,c).可以支持a、a,b、a,b,c3種組合進(jìn)行查找,但不支持b,c進(jìn)行查找.當(dāng)最左側(cè)字段是常量引用時(shí),索引就十分有效。
2、利用索引中的附加列,您可以縮小搜索的范圍,但使用一個(gè)具有兩列的索引不同于使用兩個(gè)單獨(dú)的索引。
復(fù)合索引的結(jié)構(gòu)與電話簿類似,人名由姓和名構(gòu)成,電話簿首先按姓氏對(duì)進(jìn)行排序,然后按名字對(duì)有相同姓氏的人進(jìn)行排序。
如果您知道姓,電話簿將非常有用;如果您知道姓和名,電話簿則更為有用,但如果您只知道名不知道姓,電話簿將沒(méi)有用處。
以上就是動(dòng)力節(jié)點(diǎn)Java培訓(xùn)機(jī)構(gòu)小編介紹的“程序員必須掌握的Java數(shù)據(jù)庫(kù)面試題及答案”的內(nèi)容,希望對(duì)大家有幫助,如有疑問(wèn),請(qǐng)?jiān)诰€咨詢,有專業(yè)老師隨時(shí)為你服務(wù)。
相關(guān)推薦
相關(guān)閱讀
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
有基礎(chǔ) 直達(dá)就業(yè)
業(yè)余時(shí)間 高薪轉(zhuǎn)行
工作1~3年,加薪神器
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問(wèn)老師會(huì)電話與您溝通安排學(xué)習(xí)