Mysql

從 MyISAM 到 InnoDB 的 ALTER TABLE 引擎:為什麼 mysqldump –order-by-primary 對我有幫助?

  • June 5, 2016

我在MySQL 5.7 Reference Manual中發現了一個有趣的mysqldump選項。在網際網路上沒有進一步的細節和解釋。

--order-by-primary

如果存在這樣的索引,則轉儲按其主鍵或按其第一個唯一索引排序的每個表的行。這在轉儲要載入到 InnoDB 表中的 MyISAM 表時很有用,但會使轉儲操作花費相當長的時間。

你能解釋一下為什麼這有助於將 MyISAM 遷移到 InnoDB 嗎?這是如何工作的?

MyISAM 表儲存為,行被放置在數據文件中的一個可以容納的空位置。如果您只是插入,那麼這意味著追加新行,但是當更新或刪除行時,會創建一些間隙,然後由其他行填充,因此全表掃描的順序(這是預設情況下轉儲所做的)是沒有以任何方式定義。

InnoDB 表的組織方式不同。這些行作為項目儲存在由主鍵“索引”的 B 樹中。所以整個表由定義的 PRIMARY 索引聚集。(作為旁注,InnoDB 表總是有一個 PK,如果你沒有定義一個,它會為你選擇一個或創建一個人工的。)這意味著全表掃描實際上是通過掃描 PRIMARY 索引的所有數據頁來執行的,並且所以這些行是按順序返回的。

如果您轉儲由 PRIMARY 排序的 MyISAM 表,則轉儲可能比無序的要慢一些,但轉儲通常是遷移中較快的部分,因此這主要是一個小損失。

當您將數據插入 InnoDB 表時,B-Tree 索引會動態平衡自身以保持對數深度。這通常意味著完成了一些頁面拆分。

如果以隨機順序插入數據,每一行可能會進入樹的不同部分,訪問磁碟上的不同頁面並啟動隨機拆分。這會導致一些 IO 性能損失,並且可能導致次優填充因子(每頁中空白空間的百分比),因為頁被分成兩頁,只有 50% 已滿,這意味著在糟糕的情況下,您的數據儲存可能會大 2 倍比需要的多(並且所有查詢都必須讀取兩倍的數據)。另一個可能的結果是頁面碎片 - 當 B 樹最低級別的邏輯連續頁面儲存在磁碟驅動器的隨機單獨位置時(但這種狀態不容易辨識並且似乎是一個理論上的問題,在實踐中很少遇到(如果有的話)。

但是,如果您插入按 PRIMARY KEY 排序的數據,則新行將“附加”到表中。只需要處理每個級別的“最後”頁面(如果我理解正確 - 可以避免次優填充因子,因為 InnoDB 可以辨識“附加”正在發生並更有效地添加新頁面)。頁面也可以按順序分配。

因此,以 PK 順序插入會導致更快的執行速度,並可能在 InnoDB 表中更好地使用儲存空間。

引用自:https://dba.stackexchange.com/questions/140422