Table 在 ALTER 中使用多个操作遍历 TABLE
Table traversing with multiple operations in ALTER TABLE
一些数据库,例如 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] 也实现了这一点,将在一次扫描中执行所有操作:
The main reason for providing the option to specify multiple changes in a single ALTER TABLE is that multiple table scans or rewrites can thereby be combined into a single pass over the table.
虽然对于 DROP COLUMN 来说通常甚至不需要这样做:
The DROP COLUMN form does not physically remove the column, but simply makes it invisible to SQL operations...
问题:
- 多列语句是否会导致只遍历所有行一次并执行所有需要的更改?
- MySQL 实际上是如何执行 DROP COLUMN 的?它也是先 "hide" 列,还是直接删除数据?
假设:
- 使用 InnoDB
- 没有 indexes/complex 默认值涉及我们想要 change/drop 的任何列(所以基本上改变不需要临时 table 当 运行 作为个人改变陈述)
参考文献:
MySQL 的 InnoDB:
(这 不是 真正回答了问题,但提供了对 ALTER
更大问题的更多见解。)
如果任何更改需要复制 table,您 可能 最好将所有更改放在同一个语句中。例如,更改 PRIMARY KEY
需要重建与 PK 聚类的数据。
一些改变可以通过简单地改变模式来实现;这些几乎是瞬时的,可以通过单独的 alter 语句来完成。添加选项 ENUM
很久以前就实现了。
一些 alter 需要某种形式的扫描,但可以做到 "in the background"。 DROP INDEX
可以通过快速 "hiding" 完成,然后在后台释放 BTree。
我遗漏了一个灰色区域,您可以在其中批量 'simple' 更改。人们希望 ALTER
足够聪明,可以简单地快速浏览它们,而不是决定将 table 复制过来。
我得到了一些有用的反馈,但决定回答我自己的问题以提供更具体的答案。
Would the multi-column statement result in traversing all the rows just once and performing all changes needed?
是,如果alter语句导致重建table那么它只需要做一次。*
* 这个答案来自我自己的测试和其他主要是轶事证据(包括@Uueerdo 在这个 post 中)。如果有一些官方文档会很有用...
How does MySQL actually perform DROP COLUMN? Does it also "hide" the columns first, or does it delete the data straight away?
MySQL 将为大多数列操作就地重建 table(而不是创建副本或仅更改元数据)。每个具体案例都可以在 Online DDL docs for InnoDB.
中找到
重命名列或设置默认值等一些操作只会更改元数据,因此不需要 table 重建。
但是,删除列确实需要完整的table重建。
一些数据库,例如 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] 也实现了这一点,将在一次扫描中执行所有操作:
The main reason for providing the option to specify multiple changes in a single ALTER TABLE is that multiple table scans or rewrites can thereby be combined into a single pass over the table.
虽然对于 DROP COLUMN 来说通常甚至不需要这样做:
The DROP COLUMN form does not physically remove the column, but simply makes it invisible to SQL operations...
问题:
- 多列语句是否会导致只遍历所有行一次并执行所有需要的更改?
- MySQL 实际上是如何执行 DROP COLUMN 的?它也是先 "hide" 列,还是直接删除数据?
假设:
- 使用 InnoDB
- 没有 indexes/complex 默认值涉及我们想要 change/drop 的任何列(所以基本上改变不需要临时 table 当 运行 作为个人改变陈述)
参考文献:
MySQL 的 InnoDB:
(这 不是 真正回答了问题,但提供了对 ALTER
更大问题的更多见解。)
如果任何更改需要复制 table,您 可能 最好将所有更改放在同一个语句中。例如,更改
PRIMARY KEY
需要重建与 PK 聚类的数据。一些改变可以通过简单地改变模式来实现;这些几乎是瞬时的,可以通过单独的 alter 语句来完成。添加选项
ENUM
很久以前就实现了。一些 alter 需要某种形式的扫描,但可以做到 "in the background"。
DROP INDEX
可以通过快速 "hiding" 完成,然后在后台释放 BTree。我遗漏了一个灰色区域,您可以在其中批量 'simple' 更改。人们希望
ALTER
足够聪明,可以简单地快速浏览它们,而不是决定将 table 复制过来。
我得到了一些有用的反馈,但决定回答我自己的问题以提供更具体的答案。
Would the multi-column statement result in traversing all the rows just once and performing all changes needed?
是,如果alter语句导致重建table那么它只需要做一次。*
* 这个答案来自我自己的测试和其他主要是轶事证据(包括@Uueerdo 在这个 post 中)。如果有一些官方文档会很有用...
How does MySQL actually perform DROP COLUMN? Does it also "hide" the columns first, or does it delete the data straight away?
MySQL 将为大多数列操作就地重建 table(而不是创建副本或仅更改元数据)。每个具体案例都可以在 Online DDL docs for InnoDB.
中找到重命名列或设置默认值等一些操作只会更改元数据,因此不需要 table 重建。
但是,删除列确实需要完整的table重建。