表遍历ALTER TABLE中的多个操作

时间:2018-05-14 16:18:46

标签: mysql innodb

某些数据库,如MySQL [1] 和PostgreSQL [2] ,支持捆绑某些兼容的ALTER TABLE语句(作为非标准SQL)。

例如我们可以:

ALTER TABLE `my_table`
    DROP COLUMN `column_1`,
    DROP COLUMN `column_2`,
    ...

ALTER TABLE
    MODIFY `column_1` ... ,
    MODIFY `column_2` ... ,

而不是单独的陈述:

ALTER TABLE `my_table` DROP COLUMN `column_1`;
ALTER TABLE `my_table` DROP COLUMN `column_2`;

ALTER TABLE `my_table` MODIFY `column_1` ... ;
ALTER TABLE `my_table` MODIFY `column_2` ... ;

为了比较相同的功能,PostgreSQL [2] 也实现了这一功能,它将在一次扫描中执行所有操作:

  

提供在单个ALTER TABLE中指定多个更改的选项的主要原因是,可以将多个表扫描或重写组合成表中的单个传递。

虽然对于DROP COLUMN来说,它通常甚至不需要这样做:

  

DROP COLUMN表单没有物理删除列,只是让它对SQL操作不可见......

问题:

  • 多列语句会导致只遍历所有行并执行所需的所有更改吗?
  • MySQL如何实际执行DROP COLUMN?它是否还首先“隐藏”列,还是立即删除数据?

假设:

  • 使用InnoDB
  • 我们想要更改/删除的任何列都不涉及索引/复杂默认值(所以基本上更改在作为单独的alter语句运行时不需要临时表)

参考文献:

2 个答案:

答案 0 :(得分:1)

MySQL的InnoDB:

(这不是真正回答问题,但对ALTER这个更大的问题提供了更多的见解。)

  • 如果任何更改需要复制表,那么可能最好将所有更改放在同一个语句中。例如,更改PRIMARY KEY需要重建使用PK群集的数据。

  • 通过简单地改变模式可以实现一些改变;这些几乎是即时的,可以通过单独的alter语句完成。很久以前就已经实现了向ENUM添加选项。

  • 有些修改需要某种形式的扫描,但可以“在后台”进行。 DROP INDEX可以通过快速“隐藏”它来完成,然后在后台释放BTree。

  • 我遗漏了一个灰色区域,批量“简单”改变了。人们希望ALTER足够聪明,可以快速完成它们,而不是决定复制表格。

答案 1 :(得分:0)

我得到了一些有用的反馈,但我决定回答我自己的问题,以提供更具体的答案。

  

多列语句会导致只遍历所有行并执行所需的所有更改吗?

,如果alter语句导致重建表,那么它只需要执行一次。*

*这个答案来自我自己的测试和其他大多数轶事证据(包括@Uueerdo在这篇文章中)。为此提供一些官方文档会很有用......

  

MySQL如何实际执行DROP COLUMN?它是否也首先“隐藏”列,还是立即删除数据?

MySQL将为大多数列操作重建适当的表(而不是创建副本或只更改元数据)。每个具体案例都可以在Online DDL docs for InnoDB

中找到

重命名列或设置默认值等一些操作只会改变元数据,因此它们不需要重建表。

但是,删除列需要进行全表重建