二級索引:葉子節點中存儲主鍵值,每次查找數據時,根據索引找到葉子節點中的主鍵值,根據主鍵值再到聚簇索引中得到完整的一行記錄。
問題:
1.相比於葉子節點中存儲行指針,二級索引存儲主鍵值會占用更多的空間,那為什么要這樣設計呢?
InnoDB在移動行時,無需維護二級索引,因為葉子節點中存儲的是主鍵值,而不是指針。
2.那么InnoDB有了聚簇索引,為什么還要有二級索引呢?
聚簇索引的葉子節點存儲了一行完整的數據,而二級索引只存儲了主鍵值,相比於聚簇索引,占用的空間要少。當我們需要為表建立多個索引時,如果都是聚簇索引,那將占用大量內存空間,所以InnoDB中主鍵所建立的是聚簇索引,而唯一索引、普通索引、前綴索引等都是二級索引。
3.為什么一般情況下,我們建表的時候都會使用一個自增的id來作為我們的主鍵?
InnoDB中表中的數據是直接存儲在主鍵聚簇索引的葉子節點中的,每插入一條記錄,其實都是增加一個葉子節點,如果主鍵是順序的,只需要把新增的一條記錄存儲在上一條記錄的后面,當頁達到最大填充因子的時候,下一跳記錄就會寫入新的頁中,這種情況下,主鍵頁就會近似於被順序的記錄填滿。
若表的主鍵不是順序的id,而是無規律數據,比如字符串,InnoDB無法加單的把一行記錄插入到索引的最后,而是需要找一個合適的位置(已有數據的中間位置),甚至產生大量的頁分裂並且移動大量數據,在尋找合適位置進行插入時,目標頁可能不在內存中,這就導致了大量的隨機IO操作,影響插入效率。除此之外,大量的頁分裂會導致大量的內存碎片。
Explain使用說明: