InnoDB索引【Mysql InnoDB系列】

聚集索引和二級索引


每個InnoDB表都有一個特殊的索引叫做聚集索引(clustered index),這個索引上存放了所有表中的行。通常,聚集索引是主鍵的同義詞。

  • 若在表上定義了主鍵,那麼就會把這個主鍵作爲聚集索引。最好給每張表都定義一個主鍵。如果沒有邏輯上唯一非空的一列或多列,就給表加一個自增的列作爲主鍵。
  • 若沒有定義主鍵,mysql會使用第一個沒有Null值的唯一索引作爲聚集索引
  • 若沒有主鍵或合適的唯一索引,InnoDB會內部生成一個叫做gen_clust_index的隱藏聚集索引,這個索引包含所有列和一個行ID。行是按照行ID的順序排列的。行ID是一個6字節的區域,新行寫入是單調遞增。因此,行的排列順序是按照物理寫入的順序。

聚集索引如何加速查詢


通過聚集索引訪問一行是很快的,因爲掃描索引可以直接定位一整行的數據。如果表很大,相較於那種將行數據分散在不同索引記錄頁的存儲結構,聚集索引的這種結構更加節約磁盤IO操作。

二級索引和聚集索引之間的關係


所有非聚集索引都是二級索引。在InnoDB中,每個二級索引中的記錄都含有對應的主鍵列值,也就是這個二級索引中的唯一標誌。InnoDB就是通過主鍵列值來搜索聚集索引中的行。

如果主鍵很長,那二級索引自然就會佔用更多的空間,所以最好使用較短的主鍵。

索引的物理結構


除了空間索引之外,InnoDB索引都使用B-tree數據結構。空間索引使用R-trees,這是一種專門用於多維數據的特殊的索引結構。索引記錄存放在B-tree或R-tree結構的葉子頁上。索引頁的默認大小爲16k。

當新紀錄寫入聚集索引時,每個頁會預留1/16的空間來用於將來可能出現的insert或update。如果索引記錄是順序寫入(升序或降序),索引頁可以被填充至大約15/16。若記錄是以隨機的順序寫入,索引頁的飽滿程度約爲1/2至15/16區間。

當創建或重建B-tree索引時,InnoDB使用的是批量加載的方式。這種索引創建方式叫做排序索引創建(sorted index build)。InnoDB_fill_factor變量規定了每個B-tree索引頁在被批量加載時填充的飽滿程度百分比(在15/16的基礎上)。innodb_fill_factor默認值爲100,表示預留1/16用於索引頁後續增長。另外,R-tree空間索引不支持排序索引創建。

排序序索引創建

創建索引分三個階段,第一階段會掃描聚集索引,然後生成索引條目並加入排序緩存。當排序緩存佔滿時,會使用外部臨時文件。第二階段將第一階段生成的多個排序結果進行合併排序。第三階段將最終排序結果寫入B-tree。

如果一個InnoDB索引頁的填充比降低至低於MERGE_THRESHOLD(默認爲最大值50,最小爲1),InnoDB會嘗試將索引頁(相鄰的)合併以釋放空間。

也可以設定表級別MERGE_THRESHOLD(對該表上所有索引生效):

ALTER TABLE t1 COMMENT='MERGE_THRESHOLD=40';

甚至是索引級別MERGE_THRESHOLD:

ALTER TABLE t1 ADD KEY id_index (id) COMMENT 'MERGE_THRESHOLD=40';

但對於自動生成的聚集索引GEN_CLUST_INDEX,只能使用表級別的或實例級別的MERGE_THRESHOLD

innodb_page_size配置選項用於爲Mysql實例中的所有InnoDB表空間定義頁面大小(page size)。這個選項只能在初始化實例時配置。頁面大小支持64KB,32KB,16KB,8KB和4KB,其中32KB和64KB是5.7中新加入的支持,16KB爲默認大小。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章