Mannoj Asked: 2015-01-03 08:54:17 +0800 CST2015-01-03 08:54:17 +0800 CST 2015-01-03 08:54:17 +0800 CST 删除表的多个 KEY 772 在表中删除多个 KEYS 是首选选项还是首选一个接一个? “放置键 A,放置键 B,放置键 C” 表中超过 9 亿条记录。 它在内部是如何工作的? mysql innodb 1 个回答 Voted Best Answer RolandoMySQLDBA 2015-01-03T09:26:21+08:002015-01-03T09:26:21+08:00 在一个 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。 至于我的回答,它只适用于 你删除一个索引并创建一个同名的索引 删除/添加主键
在一个 SQL 命令中删除多个索引要好得多。为什么 ?
情景#1
这就是会发生的事情
在
#SCENARIO #1
中,这会发生 3 次。情景#2
你相信 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今天所做的是:
因此,您可以相信 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 刚刚发表了评论。
@eroomydna 指出这一点是正确的。他提供的 URL 对此有所了解。
对于您的特定问题,@eroomydna 说不需要pt-online-schema-change,在这种情况下他是对的,因为您要删除三个索引。注意快速索引创建的实施细节,第 2 段:
您有一个 9 亿个表,并且可能有很多用于三个索引的索引页。删除索引是以逻辑方式完成的,并且必须使所有这些页面无效以使空间可重用。这也将创建许多允许读取和阻塞写入的共享锁。所以,这个操作应该比较快。我不能告诉你需要多长时间。既然你说你不能采取停机时间,那么对于一个有很多共享锁和阻塞写入的活动表来说,它可能是几秒钟、几分钟甚至几小时。
如果您在 DEV 或测试服务器上有表的副本,请运行
DROP KEY A,DROP KEY B,DROP KEY C
just 以便查看它的运行速度。然后,您可以考虑停机是否值得。尽管如此,如果您希望表格处于活动状态并且真的无法停机,您仍然应该使用pt-online-schema-change。至于我的回答,它只适用于