MySQL 聚簇索引 和 非聚簇索引

非聚簇索引

索引節點的葉子頁面就好比一片葉子。葉子頭便是索引鍵值。

先創建一張表:

CREATE TABLE `user` ( 
`id` INT NOT NULL ,
`name` VARCHAR NOT NULL ,
`class` VARCHAR NOT NULL);

對於MYISAM引擎,如果創建 id 和 name 爲索引。對於下面查詢:

select * from user where id = 1

會利用索引,先在索引樹中快速檢索到 id,但是要想取到id對應行數據,必須找到改行數據在硬盤中的存儲位置,因此MYISAM引擎的索引 葉子頁面上不僅存儲了主鍵id 還存儲着 數據存儲的地址信息。如圖:

這裏寫圖片描述

像這樣的索引就稱爲非聚簇索引。

非聚簇索引的二級索引與主鍵索引類似。假設我們對name添加索引,那麼name的索引樹葉子將是如下結構:

這裏寫圖片描述

聚簇索引

對於 非聚簇索引 來說,每次通過索引檢索到所需行號後,還需要通過葉子上的磁盤地址去磁盤內取數據(回行)消耗時間。爲了優化這部分回行取數據時間,InnoDB 引擎採用了聚簇索引。
聚簇索引,即將數據存入索引葉子頁面上。對於 InnoDB 引擎來說,葉子頁面不再存該行對應的地址,而是直接存儲數據:

這裏寫圖片描述

這樣便避免了回行操作所帶來的時間消耗。 使得 InnoDB 在某些查詢上比 MyISAM 還要快!

ps. 關於查詢時間,一般認爲 MyISAM 犧牲了功能換取了性能,查詢更快。但事實並不一定如此。多數情況下,MyISAM 確實比 InnoDB 查的快 。但是查詢時間受多方面因素影響。InnoDB 查詢變慢得原因是因爲支持事務、回滾等等,使得 InnoDB的葉子頁面實際上還包含有事務id(換句話說就是版本號) 以及回滾指針。

在二級索引方面, InnoDB 與 MyISAM 有很大區別。

InnoDB默認對主鍵建立聚簇索引。如果你不指定主鍵,InnoDB會用一個具有唯一且非空值的索引來代替。如果不存在這樣的索引,InnoDB會定義一個隱藏的主鍵,然後對其建立聚簇索引。一般來說,InnoDB 會以聚簇索引的形式來存儲實際的數據,它是其它二級索引的基礎。

假設對 InnoDB 引擎上表name字段加索引,那麼name索引葉子頁面則只會存儲主鍵id:

這裏寫圖片描述

檢索時,先通過name索引樹找到主索引id,再通過id在主索引樹的聚簇索引葉子頁面取出數據。

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