一些数据库,如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表中指定多个更改的选项的主要原因是,可以将多个表扫描或重写合并为对表的一次传递。
尽管对于drop column,通常甚至不需要这样做:
drop column表单不会从物理上删除该列,而只是使它对sql操作不可见。。。
问题:
多列语句是否会导致只遍历一次所有行并执行所需的所有更改?
mysql实际上是如何执行dropcolumn的?它是先“隐藏”列,还是直接删除数据?
假设:
使用innodb
在我们要更改/删除的任何列中都不涉及索引/复杂的默认值(因此基本上,当作为单个alter语句运行时,不需要临时表的更改)
参考文献:
[1] mysql alter表文档
[2] postgresql alter table文档
2条答案
按热度按时间6qfn3psc1#
mysql的innodb:
(这并不能真正回答这些问题,但在更大的问题上提供了更多的见解
ALTER
.)如果任何一个alter需要复制表,那么最好将所有alter放在同一个语句中。更改
PRIMARY KEY
例如,需要重建与pk一起聚集的数据。一些改变可以通过简单地改变模式来实现;这些实际上是即时的,可以通过单独的alter语句来完成。向添加选项
ENUM
早就实施了。有些改动需要某种形式的扫描,但可以在“后台”进行。
DROP INDEX
可以通过快速“隐藏”它,然后释放背景中的btree来完成。我遗漏了一个灰色区域,在这个灰色区域中,您可以批量进行“简单”更改。人们希望
ALTER
聪明到只需快速浏览,而不是决定复制表格。yhuiod9q2#
我得到了一些有用的反馈,但决定回答我自己的问题,提供一套更具体的答案。
多列语句是否会导致只遍历一次所有行并执行所需的所有更改?
是的,如果alter语句导致重建表,那么它只需要做一次*
mysql实际上是如何执行dropcolumn的?它是先“隐藏”列,还是直接删除数据?
mysql将为大多数列操作就地重建表(而不是创建副本或仅仅更改元数据)。每个具体案例都可以在innodb的在线ddl文档中找到。
一些操作(如重命名列或设置默认值)只会更改元数据,因此不需要重新生成表。
但是,删除列确实需要重新生成完整表。