《轉》MyISAM和InnoDB的索引實現

2021-08-01 03:57:11 字數 2449 閱讀 5108

在 mysql 中,主要有四種型別的索引,分別為: b-tree 索引, hash 索引, fulltext 索引和 r-tree 索引。我們主要分析b-tree 索引。

b-tree 索引是 mysql 資料庫中使用最為頻繁的索引型別,除了 archive 儲存引擎之外的其他所有的儲存引擎都支援 b-tree 索引。archive 引擎直到 mysql 5.1 才支援索引,而且只支援索引單個 auto_increment 列。

不僅僅在 mysql 中是如此,實際上在其他的很多資料庫管理系統中b-tree 索引也同樣是作為最主要的索引型別,這主要是因為 b-tree 索引的儲存結構在資料庫的資料檢索中有非常優異的表現。

一般來說, mysql 中的 b-tree 索引的物理檔案大多都是以 balance tree 的結構來儲存的,也就是所有實際需要的資料都存放於 tree 的 leaf node(葉子節點) ,而且到任何乙個 leaf node 的最短路徑的長度都是完全相同的,所以我們大家都稱之為 b-tree 索引。當然,可能各種資料庫(或 mysql 的各種儲存引擎)在存放自己的 b-tree 索引的時候會對儲存結構稍作改造。如 innodb 儲存引擎的 b-tree 索引實際使用的儲存結構實際上是 b+tree,也就是在 b-tree 資料結構的基礎上做了很小的改造,在每乙個leaf node 上面出了存放索引鍵的相關資訊之外,還儲存了指向與該 leaf node 相鄰的後乙個 leafnode 的指標資訊(增加了順序訪問指標),這主要是為了加快檢索多個相鄰 leaf node 的效率考慮。

下面主要討論myisam和innodb兩個儲存引擎的索引實現方式:

1)主鍵索引:

(圖myisam1)
這裡設表一共有三列,假設我們以col1為主鍵,圖myisam1是乙個myisam表的主索引(primary key)示意。可以看出myisam的索引檔案僅僅儲存資料記錄的位址。

2)輔助索引(secondary key)

在myisam中,主索引和輔助索引(secondary key)在結構上沒有任何區別,只是主索引要求key是唯一的,而輔助索引的key可以重複。如果我們在col2上建立乙個輔助索引,則此索引的結構如下圖所示:

同樣也是一顆b+tree,data域儲存資料記錄的位址。因此,myisam中索引檢索的演算法為首先按照b+tree搜尋演算法搜尋索引,如果指定的key存在,則取出其data域的值,然後以data域的值為位址,讀取相應資料記錄。

myisam的索引方式也叫做「非聚集」的,之所以這麼稱呼是為了與innodb的聚集索引區分。

innodb索引實現

然innodb也使用b+tree作為索引結構,但具體實現方式卻與myisam截然不同.

1)主鍵索引:

myisam索引檔案和資料檔案是分離的,索引檔案僅儲存資料記錄的位址。而在innodb中,表資料檔案本身就是按b+tree組織的乙個索引結構,這棵樹的葉節點data域儲存了完整的資料記錄。這個索引的key是資料表的主鍵,因此innodb表資料檔案本身就是主索引。

(圖inndb主鍵索引)

(圖inndb主鍵索引)是innodb主索引(同時也是資料檔案)的示意圖,可以看到葉節點包含了完整的資料記錄。這種索引叫做聚集索引。因為innodb的資料檔案本身要按主鍵聚集,所以innodb要求表必須有主鍵(myisam可以沒有),如果沒有顯式指定,則mysql系統會自動選擇乙個可以唯一標識資料記錄的列作為主鍵,如果不存在這種列,則mysql自動為innodb表生成乙個隱含字段作為主鍵,這個字段長度為6個位元組,型別為長整形。

2). innodb的輔助索引

innodb的所有輔助索引都引用主鍵作為data域。例如,下圖為定義在col3上的乙個輔助索引:

innodb 表是基於聚簇索引建立的。因此innodb 的索引能提供一種非常快速的主鍵查詢效能。不過,它的輔助索引(secondary index, 也就是非主鍵索引)也會包含主鍵列,所以,如果主鍵定義的比較大,其他索引也將很大。如果想在表上定義 、很多索引,則爭取盡量把主鍵定義得小一些。innodb 不會壓縮索引。

文字元的ascii碼作為比較準則。聚集索引這種實現方式使得按主鍵的搜尋十分高效,但是輔助索引搜尋需要檢索兩遍索引:首先檢索輔助索引獲得主鍵,然後用主鍵到主索引中檢索獲得記錄。

不同儲存引擎的索引實現方式對於正確使用和優化索引都非常有幫助,例如知道了innodb的索引實現後,就很容易明白1、為什麼不建議使用過長的字段作為主鍵,因為所有輔助索引都引用主索引,過長的主索引會令輔助索引變得過大。再例如,2、用非單調的字段作為主鍵在innodb中不是個好主意,因為innodb資料檔案本身是一顆b+tree,非單調的主鍵會造成在插入新記錄時資料檔案為了維持b+tree的特性而頻繁的**調整,十分低效,而使用自增字段作為主鍵則是乙個很好的選擇。

innodb索引和myisam索引的區別:

一是主索引的區別,innodb的資料檔案本身就是索引檔案。而myisam的索引和資料是分開的。

InnoDB和MyIsAM的區別

myisam型別不支援事務處理等高階處理,而innodb型別支援 這是網上對myisam和innodb的解釋,很抽象吧,我們用白話的方式解釋一下 其實也比較簡單 所謂事務處理,就是原子性操作。打個比方,支援事務處理的innodb表,建設乙個中,發帖是給積分的。你發了乙個帖子執行乙個insert語句,...

MyISAM和InnoDB的區別

mysql預設採用的是myisam。myisam不支援事務,而innodb支援。innodb的autocommit預設是開啟的,即每條sql語句會預設被封裝成乙個事務,自動提交,這樣會影響速度,所以最好是把多條sql語句顯示放在begin和commit之間,組成乙個事務去提交。innodb支援資料行...

Myisam和InnoDB的區別

mysql預設採用的是myisam。myisam不支援事務,而innodb支援。innodb的autocommit預設是開啟的,即每條sql語句會預設被封裝成乙個事務,自動提交,這樣會影響速度,所以最好是把多條sql語句顯示放在begin和commit之間,組成乙個事務去提交。innodb支援資料行...