天天看點

mysql索引

mysql索引
mysql索引
mysql索引
mysql索引
mysql索引
mysql索引
mysql索引
mysql索引

B+Tree是在B-Tree基礎上的一種優化,使其更适合實作外存儲索引結構,InnoDB存儲引擎就是用B+Tree實作其索引結構。

從上一節中的B-Tree結構圖中可以看到每個節點中不僅包含資料的key值,還有data值。而每一個頁的存儲空間是有限的,如果data資料較大時将會導緻每個節點(即一個頁)能存儲的key的數量很小,當存儲的資料量很大時同樣會導緻B-Tree的深度較大,增大查詢時的磁盤I/O次數,進而影響查詢效率。在B+Tree中,所有資料記錄節點都是按照鍵值大小順序存放在同一層的葉子節點上,而非葉子節點上隻存儲key值資訊,這樣可以大大加大每個節點存儲的key值數量,降低B+Tree的高度。

B+Tree相對于B-Tree有幾點不同:

非葉子節點隻存儲鍵值資訊。

所有葉子節點之間都有一個鍊指針。

資料記錄都存放在葉子節點中。

InnoDB存儲引擎中頁的大小為16KB,一般表的主鍵類型為INT(占用4個位元組)或BIGINT(占用8個位元組),指針類型也一般為4或8個位元組,也就是說一個頁(B+Tree中的一個節點)中大概存儲16KB/(8B+8B)=1K個鍵值(因為是估值,為友善計算,這裡的K取值為〖10〗3)。也就是說一個深度為3的B+Tree索引可以維護103 * 10^3 * 10^3 = 10億 條記錄。

實際情況中每個節點可能不能填充滿,是以在資料庫中,B+Tree的高度一般都在24層。[mysql](http://lib.csdn.net/base/mysql)的InnoDB存儲引擎在設計時是将根節點常駐記憶體的,也就是說查找某一鍵值的行記錄時最多隻需要13次磁盤I/O操作。

<code>注意</code>:在innodb中,在聚簇索引之上建立的索引稱之為輔助索引,非聚簇索引都是輔助索引,像複合索引、字首索引、唯一索引。輔助索引葉子節點存儲的不再是行的實體位置,而是主鍵值,輔助索引通路資料總是需要二次查找。

mysql索引

InnoDB中

InnoDB使用的是聚簇索引,将主鍵組織到一棵B+樹中,而行資料就儲存在葉子節點上,若使用"where id = 14"這樣的條件查找主鍵,則按照B+樹的檢索算法即可查找到對應的葉節點,之後獲得行資料。

若對Name列進行條件搜尋,則需要兩個步驟:第一步在輔助索引B+樹中檢索Name,到達其葉子節點擷取對應的主鍵。第二步使用主鍵在主索引B+樹種再執行一次B+樹檢索操作,最終到達葉子節點即可擷取整行資料。(重點在于通過其他鍵需要建立輔助索引)

聚簇索引預設是主鍵,如果表中沒有定義主鍵,InnoDB 會選擇一個唯一且非空的索引代替。如果沒有這樣的索引,InnoDB 會隐式定義一個主鍵(類似oracle中的RowId)來作為聚簇索引。如果已經設定了主鍵為聚簇索引又希望再單獨設定聚簇索引,必須先删除主鍵,然後添加我們想要的聚簇索引,最後恢複設定主鍵即可。

MYISAM

MyISAM使用的是非聚簇索引,非聚簇索引的兩棵B+樹看上去沒什麼不同,節點的結構完全一緻隻是存儲的内容不同而已,主鍵索引B+樹的節點存儲了主鍵,輔助鍵索引B+樹存儲了輔助鍵。表資料存儲在獨立的地方,這兩顆B+樹的葉子節點都使用一個位址指向真正的表資料,對于表資料來說,這兩個鍵沒有任何差别。由于索引樹是獨立的,通過輔助鍵檢索無需通路主鍵的索引樹。

mysql索引

繼續閱讀