ALTER TABLE ADD COLUMN需要很长时间


73

我只是想在数据库中的表(main_table)中添加一个名为“ location”的列。我运行的命令是

ALTER TABLE main_table ADD COLUMN location varchar (256);

main_table包含> 2,000,000行。它持续运行超过2小时,但仍未完成。

我试图用来mytop 监视此数据库的活动,以确保该查询未被其他查询过程锁定,但似乎没有。应该花那么长时间吗?实际上,我只是在运行此命令之前重新引导了计算机。现在此命令仍在运行。我不确定该怎么办。


由于索引和表中存在的行数,这将花费很长时间。注意:Varchar(255)
Jauzsika 2011年

我认为您应该为它指定一个默认值。也许这就是为什么要花时间吗?
Nilesh

2
NULL在这种情况下,它默认为默认值,这绝对不是为什么要花费很长时间的原因。
罗曼

MySQL 8.0.12有一个ALTER TABLE .. ADD COLUMN .. ALGORITHM=INSTANT
Rick James,

Answers:


191

您的ALTER TABLE陈述暗示mysql将不得不重写表的每一行,包括新列。由于您的行数超过200万,因此我肯定会花费大量时间,在此期间您的服务器可能大部分都是IO绑定的。通常,您会发现执行以下操作更有效:

CREATE TABLE main_table_new LIKE main_table;
ALTER TABLE main_table_new ADD COLUMN location VARCHAR(256);
INSERT INTO main_table_new SELECT *, NULL FROM main_table;
RENAME TABLE main_table TO main_table_old, main_table_new TO main_table;
DROP TABLE main_table_old;

这样,您可以在空表上添加该列,并基本上将数据写入该新表中,您确定没有锁定足够多的资源,其他任何人都不会看。


1
@Malvolio值得注意:我认为这是MySQL专有的SQL扩展...虽然不是100%肯定。
罗曼

6
即使是这样,有人最后一次使用非MySQL SQL RDBMS是什么时候?朋友不要让朋友购买Oracle。
马尔沃里奥

6
现在,动态填充“ fields_in_main_table”对于在脚本中使用将是一件好事。
Marki 2012年

5
即使此方法也必须重写整个表。我是否认为这种方法的唯一优势是它允许在添加新列时使用当前表?
迈克尔,

6
如果您有引用该表的外键,这将无济于事。
乔尼

31

我认为对此的适当答案是使用pt-online-schema-changegh-ost之类的功能

我们已经完成了超过40亿行的迁移,尽管迁移可能需要长达10天的时间,并且停机时间不到一分钟。

Percona的工作方式与上述非常相似

  • 创建一个临时表
  • 在第一个表上创建触发器(用于插入,更新,删除),以便将它们复制到临时表
  • 小批量迁移数据
  • 完成后,将表重命名为新表,然后删除另一个表

3
这种问题表明,投票或接受程度较低的解决方案有时是最佳或唯一正确的解决方案。有多少人赞成不正确的OMG这个其他解决方案。
Raul R.

@RaulR。这取决于用例。在我的用例中,另一个解决方案非常“正确”,不是每个人都在24/7的生产环境中工作。
奥斯汀·施密特

1

Alter table需要很长时间才能处理像您这样的大数据,因此请避免在这种情况下使用它,并使用如下代码:

select main_table.*, 
  cast(null as varchar(256)) as null_location, -- any column you want accepts null
  cast('' as varchar(256)) as not_null_location, --any column doesn't accept null
  cast(0 as int) as not_null_int, -- int column doesn't accept null
into new_table 
from main_table;

drop table main_table;
rename table new_table TO main_table;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.