Mysql

刪除表的多個 KEY

  • January 3, 2015

在表中刪除多個 KEYS 是首選選項還是首選一個接一個?

“放置鍵 A,放置鍵 B,放置鍵 C”

表中超過 9 億條記錄。

它在內部是如何工作的?

在一個 SQL 命令中刪除多個索引要好得多。為什麼 ?

情景#1

ALTER TABLE mytable DROP INDEX ndx1;
ALTER TABLE mytable DROP INDEX ndx2;
ALTER TABLE mytable DROP INDEX ndx3;

這就是會發生的事情

  • 創建一個空的臨時表
  • 從空的臨時表中刪除索引
  • 將數據複製到臨時表中
  • 將臨時表與原始表交換
  • 刪除原始表

#SCENARIO #1中,這會發生 3 次。

情景#2

ALTER TABLE mytable
   DROP INDEX ndx1,
   DROP INDEX ndx2,
   DROP INDEX ndx3
;

你相信 MySQL 在 2006 年的 MySQL 4.1 下曾經做過 3 次這種轉換嗎?換句話說,SCENARIO #2會像SCENARIO #1. 我實際上在 MySQL AB General Discussion Forum 上寫了一篇文章,要求對此進行更改(Why does mysql drop index very very slow in a large table?)。

有人在 DBA StackExchange 中詢問 MySQL 是否仍然這樣做。我在這裡寫了一篇文章說這不再是這種情況(MySQL 仍然以這種方式處理索引嗎?)並且這個問題引用了我原來的 MySQL AB 文章

MySQL今天所做的是:

  • 創建一個臨時表
  • 針對空臨時表執行 3 個 ALTER TABLE 命令
  • 一次將數據複製到臨時表中
  • 將臨時表與原始表交換
  • 刪除原始表

因此,您可以相信 MySQL 今天會做正確的事。

你應該和SCENARIO #2.

試一試 !!!

更新 2015-01-02 13:06 EST

你剛問

表的新操作會發生什麼?複製時新記錄將儲存在哪裡?需要表鎖還是元數據鎖?

該表將一直被鎖定。當然,SCENARIO #1只要 3 次就會被鎖定SCENARIO #2。如果您不能為此停機,您只有一個選擇:pt-online-schema-change。在更改期間,您的所有 INSERT、UPDATE 和 DELETE 都將得到妥善處理。

更新 2015-01-03 08:33 EST

@eroomydna 剛剛發表了評論

@rolando,您是否考慮過 dev.mysql.com/doc/refman/5.5/en/innodb-create-index.html 的影響,預設為 5.6。不應使用上述分組的 ddl 重建表。此操作無需使用 pt-osc。

@eroomydna 指出這一點是正確的。他提供的 URL 對此有所了解。

對於您的特定問題,@eroomydna 說不需要pt-online-schema-change,在這種情況下他是對的,因為您要刪除三個索引。注意快速索引創建的實施細節,第 2 段

刪除二級索引很簡單。只有內部 InnoDB 系統表和 MySQL 數據字典表被更新以反映索引不再存在的事實。InnoDB 將用於索引的儲存返回到包含它的表空間,以便新索引或其他表行可以使用該空間。

您有一個 9 億個表,並且可能有很多用於三個索引的索引頁。刪除索引是以邏輯方式完成的,並且必須使所有這些頁面無效以使空間可重用。這也將創建許多允許讀取和阻塞寫入的共享鎖。所以,這個操作應該比較快。我不能告訴你需要多長時間。既然你說你不能讓停機,那麼對於一個有很多共享鎖和阻塞寫入的活動表來說,它可能是幾秒鐘、幾分鐘甚至幾小時。

如果您在 DEV 或測試伺服器上有表的副本,請執行DROP KEY A,DROP KEY B,DROP KEY Cjust 以便查看它的執行速度。然後,您可以考慮停機是否值得。儘管如此,如果您希望表格處於活動狀態並且真的無法停機,您仍然應該使用pt-online-schema-change

至於我的回答,它只適用於

  • 你刪除一個索引並創建一個同名的索引
  • 刪除/添加主鍵

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