來源:mysql
《高性能mysql(第三版)》sql
假若有如下表:bash
create table test (
col1 int not null,
col2 int not null,
primary key(col1),
key(col2)
);
複製代碼
假設該表的主鍵值取值1-10000,按照隨機順序插入並使用OPTIMIZE TABLE 命令作了優化。也就是說,數據在磁盤上的存儲方式已經最優,可是行的順序是隨機的,列col2的值1-100之間的隨機值,因此有不少重複的值。性能
咱們先介紹MyISAM的數據分佈:優化
MyISAM按照數據插入的順序存儲在磁盤上,以下表:ui
行號 | col1 | col2 |
---|---|---|
0 | 99 | 8 |
1 | 12 | 56 |
2 | 3000 | 62 |
....spa
行號 | col1 | col2 |
---|---|---|
9997 | 18 | 8 |
9998 | 4700 | 13 |
9999 | 3 | 93 |
由於這裏行是定長的,因此MyISAM能夠從表的開始跳過所需的字節找到須要的行。(對於變長的行使用不一樣的策略,這裏暫不介紹)指針
這種分佈方式很容易建立索引,下圖顯示了表的主鍵分佈:code
能夠看到,葉子節點按照主鍵排序好了,並且還保存了行號。cdn
那麼MyISAM下,col2上的索引有什麼不一樣呢?答案是徹底同樣的存儲方式,只是把主鍵列換成col2列罷了。這裏就再也不贅述。
再來看InnoDB的數據分佈:
下面是InnoDB的主鍵分佈:
注意看,上圖顯示了整個表,而不是隻有索引。
由於在InnoDB中,聚簇索引 "就是"表。因此不像MyISAM那樣須要獨立的行儲存。
每一個葉子節點都包含了主鍵值,事務id, 回滾指針(用於事務和mvvc),以及全部剩餘的列(這個例子是col2)
除此之外,InnoDB的二級索引和聚簇索引很不一樣,和MyISAM的索引也不同。以下圖:
InnoDB的二級索引的葉子節點存儲的不是行號,而是主鍵值。這樣的策略減小了當出現行移動或者數據頁分裂時二級索引的維護工做。使用主鍵值當工做指針會讓二級索引佔用更多的空間,換來的好處是,InnoDB在移動行時沒必要更新二級索引的這個「指針」。
上圖咱們省略了非葉子節點的細節,它包含了索引列和一個指向下一個節點的指針。
總結