Innodb與MyIsam區別二

MyISAM引擎使用B+Tree作爲索引結構,葉節點的data域存放的是數據記錄的地址。下圖是MyISAM索引的原理圖:


這裏設表一共有三列,假設我們以Col1爲主鍵,則上圖是一個MyISAM表的主索引(Primary key)示意。可以看出MyISAM的索引文件僅僅保存數據記錄的地址。在MyISAM中,主索引和輔助索引(Secondary key)在結構上沒有任何區別,只是主索引要求key是唯一的,而輔助索引的key可以重複。如果我們在Col2上建立一個輔助索引,則此索引的結構如下圖所示
同樣也是一顆B+Tree,data域保存數據記錄的地址。因此,MyISAM中索引檢索的算法爲首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,則取出其data域的值,然後以data域的值爲地址,讀取相應數據記錄。
MyISAM的索引方式也叫做“非聚集”的,之所以這麼稱呼是爲了與InnoDB的聚集索引區分。
 
InnoDB索引實現
雖然InnoDB也使用B+Tree作爲索引結構,但具體實現方式卻與MyISAM截然不同。
第一個重大區別是InnoDB的數據文件本身就是索引文件。從上文知道,MyISAM索引文件和數據文件是分離的,索引文件僅保存數據記錄的地址。而在InnoDB中,表數據文件本身就是按B+Tree組織的一個索引結構,這棵樹的葉節點data域保存了完整的數據記錄。這個索引的key是數據表的主鍵,因此InnoDB表數據文件本身就是主索引

上圖是InnoDB主索引(同時也是數據文件)的示意圖,可以看到葉節點包含了完整的數據記錄。這種索引叫做聚集索引。因爲InnoDB的數據文件本身要按主鍵聚集,所以InnoDB要求表必須有主鍵(MyISAM可以沒有),如果沒有顯式指定,則MySQL系統會自動選擇一個可以唯一標識數據記錄的列作爲主鍵,如果不存在這種列,則MySQL自動爲InnoDB表生成一個隱含字段作爲主鍵,這個字段長度爲6個字節,類型爲長整形。
 
第二個與MyISAM索引的不同是InnoDB的輔助索引data域存儲相應記錄主鍵的值而不是地址。換句話說,InnoDB的所有輔助索引都引用主鍵作爲data域。例如,下圖爲定義在Col3上的一個輔助索引:

\

這裏以英文字符的ASCII碼作爲比較準則。聚集索引這種實現方式使得按主鍵的搜索十分高效,但是輔助索引搜索需要檢索兩遍索引:首先檢索輔助索引獲得主鍵,然後用主鍵到主索引中檢索獲得記錄。
註解
1、MyISAM 使用B+Tree 作爲索引結構,葉子節點的data存放指針,也就是記錄的地址。對於主鍵索引和輔助索引都是一樣的。
2、InnoDB 也使用B+Tree作爲索引結構,也別需要注意的是,對於主鍵索引,InnoDB 使用聚集索引,InnoDB的數據文件本身就是就是索引文件。而MyISAM,主鍵索引和數據文件是分離的。
3、InnoDB數據文件,要按主鍵聚集索引,這就要求InnoDB的表必須要有主鍵(MyISAM可以沒有)。如果沒有顯式指定主鍵,InnoDB會自動選擇一個可以唯一標識記錄的字段作爲主鍵,比如auto_increment的字段,如果不存在這樣的列,InnoDB會自動生成一個隱含字段作爲主鍵,這個隱含字段6個字節,是長整形。
4、對於InnoDB的輔助索引,葉子節點的data存放的是主鍵的值。這就意味着,使用輔助索引定位記錄,需要使用兩次索引:首先使用輔助索引找到主鍵的值,根據主鍵的值,使用主鍵索引找到記錄。
5、InnoDB的輔助索引爲什麼要這樣設計?
如果輔助索引data存放的行指針,當行移動或者數據頁分裂時,需要更新data域行指針的值,這就增加維護成本。data存在主鍵的值,就沒有這個問題。行移動和數據頁分裂,主鍵索引會自動更新。data關聯主鍵的值,不需要更新,相當於增加一個間接層。這個間接層對性能的影響也很小,因爲通過主鍵定位記錄是非常快的。
6、瞭解了innoDB的索引實現,有幾個地方需要注意:
不要使用過長的字段作爲主鍵,因爲輔助索引都要使用主鍵索引定位記錄,這個字段過長,使用內存更大,影響性能。
使用單調的字段作爲主鍵,特別是insert的時候,如果是非單調的,B+Tree維護成本很高。
7、這就能很好解釋,隔離級別 repeatable-read, 不使用索引鎖住整個表,使用索引(主鍵索引或者輔助索引)只會鎖住對應的行。
8、在查詢執行計劃中,有一個字段 type, eq_ref 表示使用主鍵索引,直接定位到記錄。而ref 表示先使用輔助索引,找到主鍵的值,再使用主鍵索引定位到記錄。

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