删除表的多个 KEYS

Man*_*noj 7 mysql innodb index alter-table

在一个表中删除多个 KEYS 是首选还是一个一个的首选?

“按键A,按键B,按键C”

表中有 9 亿多条记录。

它在内部如何运作?

Rol*_*DBA 10

在一个 SQL 命令中删除多个索引会更好。为什么 ?

情景#1

ALTER TABLE mytable DROP INDEX ndx1;
ALTER TABLE mytable DROP INDEX ndx2;
ALTER TABLE mytable DROP INDEX ndx3;
Run Code Online (Sandbox Code Playgroud)

这就是会发生的事情

  • 创建一个空的临时表
  • 从空临时表中删除索引
  • 将数据复制到临时表中
  • 用原始表交换临时表
  • 丢弃原始表

#SCENARIO #1,这将发生三遍。

场景#2

ALTER TABLE mytable
    DROP INDEX ndx1,
    DROP INDEX ndx2,
    DROP INDEX ndx3
;
Run Code Online (Sandbox Code Playgroud)

您会相信 MySQL 曾经在 2006 年在 MySQL 4.1 下进行过 3 次这种转换吗?换句话说,SCENARIO #2将像SCENARIO #1. 我实际上在 MySQL AB General Discussion Forum 中写了一篇帖子,要求对此进行更改(为什么 mysql drop index 在大表中非常非常慢?)。

有人在 DBA StackExchange 中询问 MySQL 是否仍然这样做。我在这里写了一篇文章说情况不再如此(MySQL 是否仍然以这种方式处理索引?)并且该问题引用了我原来的 MySQL AB 帖子

MySQL今天所做的是:

  • 创建临时表
  • 对空的临时表运行 3 个 ALTER TABLE 命令
  • 将数据复制到临时表中 ONCE
  • 用原始表交换临时表
  • 丢弃原始表

因此,您可以相信 MySQL 今天会做正确的事情。

你应该去SCENARIO #2

试一试 !!!

更新 2015-01-02 13:06 美国东部时间

你刚问

表的新操作会发生什么?复制时新记录将存储在哪里?需要表锁还是元数据锁?

该表将一直锁定。当然,SCENARIO #1只要 3 次就会被锁定SCENARIO #2。如果您不能为此停机,您只有一种选择:pt-online-schema-change。在更改期间,您的所有 INSERT、UPDATE 和 DELETE 都将得到正确处理。

更新 2015-01-03 08:33 美国东部时间

@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 C,以便您可以查看它的运行速度。然后,您可以考虑停机是否值得。尽管如此,如果您希望该表处于活动状态并且确实无法进行停机,您仍然应该使用pt-online-schema-change

至于我的回答,它仅适用于

  • 你删除一个索引并创建一个同名的索引
  • 删除/添加主键