mysql一张表两个索引字段是建两颗独立索引树吗?
在 MySQL 中,一個(gè)索引就是一顆 B+ 索引樹,所以這個(gè)和字段沒關(guān)系,主要看建了幾個(gè)索引
索引樹是存儲(chǔ)在磁盤上的
表
聚集索引(Clustered index )
每個(gè)InnoDB表都有一個(gè)稱為聚集索引的特殊索引,該索引是按照表的主鍵構(gòu)造的一棵B+樹。
知識(shí)點(diǎn)
- 葉子節(jié)點(diǎn)存放了整張表的所有行數(shù)據(jù)。
- 非葉子節(jié)點(diǎn)并不存儲(chǔ)行數(shù)據(jù),是為了能存儲(chǔ)更多索引鍵,從而降低 - B+樹的高度,進(jìn)而減少IO次數(shù)。
- 聚集索引的存儲(chǔ)在物理上并不是連續(xù)的,每個(gè)數(shù)據(jù)頁(yè)在不同的磁盤塊,通過一個(gè)雙向鏈表來進(jìn)行連接。
假設(shè)要查找數(shù)據(jù)項(xiàng)6
- 把根節(jié)點(diǎn)由磁盤塊0加載到內(nèi)存,發(fā)生一次IO,在內(nèi)存中用二分查找確定6在3和9之間;
- 通過指針P2的磁盤地址,將磁盤2加載到內(nèi)存,發(fā)生第二次IO,再在內(nèi)存中進(jìn)行二分查找找到6,結(jié)束。
- 這里只進(jìn)行了兩次IO,實(shí)際上,每個(gè)磁盤塊大小為4K,3層的B+樹可以表示上百萬(wàn)的數(shù)據(jù),也就是每次查找只需要3次IO,所以索引對(duì)性能的提高將是巨大的
怎樣選擇聚集索引
每張InnoDB表有且只有一個(gè)聚集索引,那它是怎么選擇索引的呢?
一般情況,用PRIMARY KEY來作為聚集索引。
如果沒有定義PRIMARY KEY,將會(huì)用第一個(gè)UNIQUE且NOT NULL的列來作為聚集索引。
如果表沒有合適的UNIQUE索引,會(huì)內(nèi)部根據(jù)行ID值生成一個(gè)隱藏的聚簇索引GEN_CLUST_INDEX。
所以在建表的時(shí)候,如果沒有邏輯唯一且非空列時(shí),可以添加一個(gè)auto_increment的列,方便建立一個(gè)聚集索引
非聚集索引(Secondary indexes)
非聚集索引又叫輔助索引,葉子節(jié)點(diǎn)并不包含行記錄數(shù)據(jù),而是存儲(chǔ)了聚集索引鍵
知識(shí)點(diǎn)
- 每個(gè)表可以有多個(gè)輔助索引
- 通過輔助索引查數(shù)據(jù)時(shí),先查找輔助索引獲得聚集索引的主鍵,然后通過主鍵索引來查找完整的行記錄。
- 通過非主鍵索引比主鍵索引查找速度要慢一倍。
查找:獲取NAME=Jake的數(shù)據(jù)
第一階段:通過輔助索引查到主鍵索引的主鍵
把idx_name索引的根節(jié)點(diǎn)由磁盤塊0加載到內(nèi)存,發(fā)生一次IO,查找到在P2指針中
根據(jù)P2指針的磁盤地址,加載磁盤塊2到內(nèi)存,發(fā)生第二次IO,查找到Jake節(jié)點(diǎn)以及它的主鍵索引9
第二階段:通過主鍵索引找到完整的行記錄
把根節(jié)點(diǎn)由磁盤塊0加載到內(nèi)存,發(fā)生一次IO,在內(nèi)存中用二分查找確定9在P3指針中
通過指針P3的磁盤地址,將磁盤3加載到內(nèi)存,發(fā)生第二次IO,再在內(nèi)存中進(jìn)行二分查找找到9,以及它的行記錄,
查找結(jié)束。
總結(jié)
以上是生活随笔為你收集整理的mysql一张表两个索引字段是建两颗独立索引树吗?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。