在 MySql 中重命名列的复杂性是什么?

Wol*_*old 6 mysql performance mysql-5.5 ddl

我们想重命名 MySql(5.5 版)数据库中的列,如下所示:

ALTER TABLE t1 CHANGE a b INTEGER;
Run Code Online (Sandbox Code Playgroud)

这是 O(N)(N=表中的行数)还是 O(1) 操作?我似乎无法在手册或谷歌上找到答案。该表有数百万条记录,如果是 O(N) 则直接不可行。

小智 6

如果仅更改名称,则它可以是O(1)操作,请参阅:

https://dev.mysql.com/doc/refman/8.0/en/alter-table.html

并搜索:

重命名、重新定义和重新排序列

那是在解释该操作仅修改表元数据的部分中。

回到MySQL 5.5,手册说它也可以在那里工作,除了 InnoDB 表。


小智 5

不幸的是,它是 O(N)。MySQL在内部创建一个具有所需结构的新表,将所有数据复制到该表中,然后最后交换数据文件以使用新表的“重命名”删除原始表。你可以在 MySQL 的手册中找到它——它被掩埋了(因此我现在找不到你的直接链接),但它就在那里。

您可以考虑我在重组大型表时使用的一种可能性,基本上是您自己采取这些相同的步骤:

  1. 创建具有所需结构的 new_table
  2. 运行 INSERT INTO new_table (SELECT * FROM old_table) -- 请注意,实际上至少对于 INSERT,您需要明确地使用列,我也建议使用 SELECT(这样您将拥有一个模式,您可以重新排序列时也遵循)。
  3. 删除原来的并重命名新的

自己做的好处是,您可以在数据库处于活动状态时进行架构更改和初始填充,然后在对在此期间可能已更改的任何数据进行最终更新之前锁定原始数据,然后进行最终交换-就位。(请注意,这假设您有某种机制——可能是一个 TIMESTAMP 字段——来识别在此期间发生变化的行。)