innodb的次索引指向對主鍵的引用 (聚簇索引)html
myisam的次索引和主索引 都指向物理行 (非聚簇索引)mysql
聚簇索引是對磁盤上實際數據從新組織以按指定的一個或多個列的值排序的算法。特色是存儲數據的順序和索引順序一致。通常狀況下主鍵會默認建立聚簇索引,且一張表只容許存在一個聚簇索引(理由:數據一旦存儲,順序只能有一種)。算法
在《數據庫原理》一書中是這麼解釋聚簇索引和非聚簇索引的區別的:
聚簇索引的葉子節點就是數據節點,而非聚簇索引的葉子節點仍然是索引節點,只不過有指向對應數據塊的指針。sql
INNODB和MYISAM的主鍵索引與二級索引的對比:數據庫
也就是InnoDB的主索引的節點與數據放在一塊兒,次索引的節點存放的是主鍵的位置。spa
myisam的主索引和次索引都指向該數據在磁盤的位置。指針
InnoDB的的二級索引的葉子節點存放的是KEY字段加主鍵值。所以,經過二級索引查詢首先查到是主鍵值,而後InnoDB再根據查到的主鍵值經過主鍵索引找到相應的數據塊。
而MyISAM的二級索引葉子節點存放的仍是列值與行號的組合,葉子節點中保存的是數據的物理地址。因此能夠看出MYISAM的主鍵索引和二級索引沒有任何區別,主鍵索引僅僅只是一個叫作PRIMARY的惟1、非空的索引,且MYISAM引擎中能夠不設主鍵
也能夠用下面這幅圖理解:code
首先是myisam的索引主次索引都指向物理行:htm
InnoDB的主索引葉子節點是主鍵和數據,次索引指向主鍵blog
innodb的主索引文件上 直接存放該行數據,稱爲聚簇索引,次索引指向對主鍵的引用
myisam中, 主索引和次索引,都指向物理行(磁盤位置).
注意: innodb來講,
1: 主鍵索引 既存儲索引值,又在葉子中存儲行的數據
2: 若是沒有主鍵, 則會Unique key作主鍵
3: 若是沒有unique,則系統生成一個內部的rowid作主鍵.
4: 像innodb中,主鍵的索引結構中,既存儲了主鍵值,又存儲了行數據,這種結構稱爲」聚簇索引」
一、聚簇索引
a) 一個索引項直接對應實際數據記錄的存儲頁,可謂「直達」
b) 主鍵缺省使用它
c) 索引項的排序和數據行的存儲排序徹底一致,利用這一點,想修改數據的存儲順序,能夠經過改變主鍵的方法(撤銷原有主鍵,另找也能知足主鍵要求的一個字段或一組字段,重建主鍵)
d) 一個表只能有一個聚簇索引(理由:數據一旦存儲,順序只能有一種)
二、非聚簇索引
a) 不能「直達」,可能鏈式地訪問多級頁表後,才能定位到數據頁
b) 一個表能夠有多個非聚簇索引
優點: 根據主鍵查詢條目比較少時,不用回行(數據就在主鍵節點下)
劣勢: 若是碰到不規則數據插入時,形成頻繁的頁分裂.
聚簇索引的頁分裂過程
理解: 原來索引以下
此時插入一個8,須要將13,16,17移動以後插入8
對於myisam引擎:只須要存儲數據以後移動索引節點,
對於innoDb的聚簇索引:插入數據以後須要移動13,16,17.可是由於這三個節點上面有數據,也就形成了額外的開銷。至關於三個節點搬家的同時帶着數據搬家。
也能夠用下圖理解:
1: innodb的buffer_page 很強大.
2: 聚簇索引的主鍵值,應儘可能是連續增加的值,而不是要是隨機值,
(不要用隨機字符串或UUID)
不然會形成大量的頁分裂與頁移動.
爲了看出效果能夠用Java向數據庫中按順序插入1000條數據與亂序插入一千條數據。看執行的時間便可看出效果。
以下圖:Innodb_pages_written表明已經寫入的頁數,能夠按順序插入1000條數據與亂序插入一千條數據觀察增加的變化量。
mysql> show status like '%page_%'; +----------------------------------+-------+ | Variable_name | Value | +----------------------------------+-------+ | Innodb_buffer_pool_pages_data | 256 | | Innodb_buffer_pool_pages_dirty | 0 | | Innodb_buffer_pool_pages_flushed | 749 | | Innodb_buffer_pool_pages_free | 243 | | Innodb_buffer_pool_pages_misc | 13 | | Innodb_buffer_pool_pages_total | 512 | | Innodb_dblwr_pages_written | 628 | | Innodb_page_size | 16384 | | Innodb_pages_created | 67 | | Innodb_pages_read | 736 | | Innodb_pages_written | 749 | | Tc_log_max_pages_used | 0 | | Tc_log_page_size | 0 | | Tc_log_page_waits | 0 | +----------------------------------+-------+ 14 rows in set (0.00 sec)
聚簇索引與非聚簇索引的區別參考:http://www.cnblogs.com/qlqwjy/p/7770580.html