Mysql

我可以從 MyISAM ALTER 中的進度報告推斷嗎?

  • December 10, 2021

我正在遷移一個 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)。

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