刪除表的多個 KEY
在表中刪除多個 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
@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 C
just 以便查看它的執行速度。然後,您可以考慮停機是否值得。儘管如此,如果您希望表格處於活動狀態並且真的無法停機,您仍然應該使用pt-online-schema-change。至於我的回答,它只適用於
- 你刪除一個索引並創建一個同名的索引
- 刪除/添加主鍵