我可以從 MyISAM ALTER 中的進度報告推斷嗎?
我正在遷移一個 3 億行的 MyISAM 表以添加一些索引。
僅僅因為它可能是相關的,這是我的
ALTER
聲明:ALTER TABLE my_table ADD UNIQUE INDEX my_table_abcd (a, b, c, d), ADD INDEX my_table_abc (a, b, c), ADD INDEX my_table_c (c), ADD INDEX my_table_ce (c, e), ADD INDEX my_table_d (a);
它目前說
Stage: 1 of 2 'copy to tmp table' 74.8% of stage done
並且 processlist 說
ALTER
語句的進度是37.440
。我不記得確切的時間,但“第一階段”的值在第一個小時左右就躍升到了 60%,而在過去的 12 個小時裡,我一直爬到了 70%。在過去的 3 個小時裡,它增加了 1.5%。
我決定是否中止此操作並嘗試更改一些配置設置或讓它執行。根據之前的觀察,它不是線性的。如果它以指數方式減速,那麼當我可以嘗試另一種方法時讓它繼續下去是一種浪費。
關於做出決定的依據有什麼想法嗎?
注意這個問題是相關的,但不是重複的。我不是問預測時間,我問的是進度報告是否與時間呈線性關係。
您有多餘的索引
而不是你的
ALTER TABLE
ALTER TABLE my_table ADD UNIQUE INDEX my_table_abcd (a, b, c, d), ADD INDEX my_table_abc (a, b, c), ADD INDEX my_table_c (c), ADD INDEX my_table_ce (c, e), ADD INDEX my_table_d (a);
你只需要兩個索引
ALTER TABLE my_table ADD UNIQUE INDEX my_table_abcd (a, b, c, d), ADD INDEX my_table_ce (c, e);
要驗證這一點,請下載pt-duplicate-key-checker並針對您的表執行它,您將看到它建議刪除這三個冗餘索引。請參閱我的文章Mysql 可能有太多關於如何執行此操作的索引。
順便說一句,您引用的我的舊文章不再適用,因為 MySQL 現在將所有結構更改應用到單個臨時表中,然後再將數據載入到其中。
至於操作本身,請中止它並從我的縮短版本重新開始。
進度報告很可能是非線性的。這是因為記憶體和排序的工作方式。
最初,一切都可以在 RAM 中發生,這比在磁碟上要快得多。隨著事情的進展,需要執行 I/O。然後 I/O 會更多地參與其中。
此外,還有一個問題是它是否決定在 RAM(在 key_buffer 中)中建構索引,而不是在磁碟上扔東西並使用作業系統的排序命令(“通過排序修復”)。(對於大表來說,後者更快。)無論哪種方式,進度都是非線性的。key_buffer 最終會填滿並崩潰。排序是 Order(N * log N)。
我認為在單個 ALTER 中添加多個索引時不會有太多的並行性。但是,批處理 ADD INDEX 可以節省多次讀取數據。所以,你做一個 ALTER 是對的。較新版本的InnoDB具有 algorithm=online,其中可以添加單個 INDEX,而對錶的影響要小得多。在這種情況下,單獨執行 ADD可能會更好。
我同意 Rolando 關於擺脫冗餘索引的觀點。INDEX(c,e) 可以處理“WHERE c=12”(並且沒有提及
e
)。