InnoDB 索引組織表緩存
1、索引組織表定義安全
在InnoDB存儲引擎中,表都是根據主鍵順序組織存放的,這種存儲方式的表稱爲索引組織表(index organized table IOT)。優化
在InnoDB存儲引擎中,每張表都有個主鍵(Primary key),若是在建立表時沒有地定義主鍵,則InnoDB存儲引擎會選擇表中符合條件的列去建立主鍵。spa
條件:設計
1. 首先判斷表中是否有非空的惟一索引(Unique NOT NULL),若是有,則該列即爲主鍵。指針
2. 若是不符合上述條件,InnoDB存儲引擎自動建立一個6字節大小的指針。code
當表中存在多個非空的惟一索引的時候,InnoDB存儲引擎會根據建表時所建立的第一個非空惟一索引做爲主鍵。blog
2、案例索引
建立test表內存
CREATE TABLE test( a INT NOT NULL , b INT NULL , c INT NOT NULL , d INT NOT NULL , UNIQUE KEY(b) , UNIQUE KEY(d) , UNIQUE KEY(c) )
初始化數據
INSERT INTO test SELECT 1,2,3,4; INSERT INTO test SELECT 5,6,7,8;
經過如下語句能夠判斷錶帶主鍵值(_rowid爲主鍵)
select *,_rowid from test;
雖然b字段索引的順序在d以前,但因爲b字段容許空值,因此依次往下排即選取d字段爲主鍵。
ps,若是爲聯合索引,那麼久無能爲力了!
3、爲何須要惟一主鍵呢?
主鍵(primary key) 一列(或一組列),其值可以惟一區分表中的每一個行。 惟一標識表中每行的這個列(或這組列)稱爲主鍵。沒有主鍵,更新或刪除表中特定行很困難,由於沒有安全的方法保證只設計相關的行。簡單的說主鍵的目的在於索引。
InnoDB引擎使用匯集索引,數據記錄自己被存於主索引(一顆B+Tree)的葉子節點上。這就要求同一個葉子節點內(大小爲一個內存頁或磁盤頁)的各條數據記錄按主鍵順序存放,所以每當有一條新的記錄插入時,MySQL會根據其主鍵將其插入適當的節點和位置,若是頁面達到裝載因子(InnoDB默認爲15/16),則開闢一個新的頁(節點)。
1. 若是表使用自增主鍵,那麼每次插入新的記錄,記錄就會順序添加到當前索引節點的後續位置,當一頁寫滿,就會自動開闢一個新的頁。以下圖所示:
這樣就會造成一個緊湊的索引結構,近似順序填滿。因爲每次插入時也不須要移動已有數據,所以效率很高,也不會增長不少開銷在維護索引上。
2. 若是使用非自增主鍵(若是身份證號或學號等),因爲每次插入主鍵的值近似於隨機,所以每次新紀錄都要被插到現有索引頁得中間。此時MySQL不得不爲了將新記錄插到合適位置而移動數據,甚至目標頁面可能已經被回寫到磁盤上而從緩存中清掉,此時又要從磁盤上讀回來,這增長了不少開銷,同時頻繁的移動、分頁操做形成了大量的碎片,獲得了不夠緊湊的索引結構,後續不得不經過OPTIMIZE TABLE來重建表並優化填充頁面。
如有不恰當之處,還望指教,謝謝!
參考書籍:
[1]. MySQL技術內幕:InnoDB存儲引擎