MySQL把表的數據詞典信息以.frm文件的形式存在數據庫目錄裡,所有MySQL存儲引擎都是這樣的。但是每個InnoDB表在表空間內的InnoDB內部數據詞典裡也有它自己的條目。當MySQL移除表或數據庫,它不得不刪除.frm文件和InnoDB數據詞典內的相應條目。這就是為什麼你不能在數據庫之間簡單地移動.frm文件來移動InnoDB表。
1、聚集索引和第二索引
每個InnoDB有一個叫聚集索引(clustered index)的特殊索引,行的數據被存於其中。
通過聚集索引訪問行速度很快,因為行數據與索引掃描頭部在同一數據頁上。如果表是巨大的,當對於那些索引與數據放在不同數據頁上的方案,聚集索引構架通常更節約磁盤I/O。(比如,MyISAM用一個文件存放數據,另外一個文件存放索引)。
在InnoDB中,非聚集索引裡的記錄(也稱為輔助索引或第二索引)包含對應行的主鍵值。InnoDB用這個主鍵值從聚集索引中搜索行。注意,如果主鍵比較長,第二索引就會使用更多空間,因此最好使用一個比較短的主鍵。
2、索引的物理結構
所有InnoDB的索引是B樹索引,這種索引記錄被存儲在樹的葉子頁上。一個索引頁的默認大小是16KB。當新記錄被插入,InnoDB會為將來索引記錄的插入和更新留下十六分之一的頁空間。
如果索引記錄以連續的順序被插入(升序或者降序),結果索引頁大約是15/16滿。如果記錄被以隨機的順序被插入,頁面是從1/2到 15/16滿。如果索引頁的填充因子降到低於1/2,InnoDB會收縮索引樹來釋放頁。
3、插入緩沖
在數據庫應用中,主鍵是一個唯一的識別符,並且新行被以主鍵的升序來插入,這是個常見的情況。因此,聚集索引的插入不需要磁盤的隨機讀。
另一方面,第二索引通常是非唯一的,第二索引的插入順序也相對隨機。這可能會導致大量的隨機磁盤I/O操作,而沒有一個被用在InnoDB中的專用機制。
如果一個索引記錄應該被插入到一個非唯一第二索引,InnoDB檢查第二索引頁是否在緩沖池中。如果是,InnoDB直接插入到索引頁。如果索引頁沒有在緩沖池中被發現,InnoDB插入記錄到一個專門的插入緩沖結構。插入緩沖被保持得如此小以至於它完全適合在緩沖池,並且可以非常快地做插入。
插入緩沖周期性地被合並到數據庫中第二索引樹裡。把數個插入合並到索引樹的同一頁,節省磁盤I/O操作,經常地這是有可能的。據測量,插入緩沖可以提高到表的插入速度達15倍。
在插入事務被提交之後,插入緩沖合並可能連續發生。實際上,服務器關閉和重啟之後,這會連續發生。
當許多第二索引必須被更新,並且許多行已被插入之時,插入緩沖合並可能需要數個小時。在這期間內,磁盤I/O將會增加,這樣會導致磁盤約束查詢明顯緩慢。另一個明顯的後台I/O操作是淨化(purge)線程