2011-09-29 176 views
52

我只是试图添加一个名为“位置”的列到数据库中的表(main_table)。我运行的命令是ALTER TABLE ADD COLUMN需要很长的时间

ALTER TABLE main_table ADD COLUMN location varchar (256); 

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

我试图使用mytop 来监视此数据库的活动,以确保查询未被其他查询进程锁定,但似乎没有。它应该需要很长时间吗?实际上,我只是在运行此命令之前重新启动机器。现在这个命令仍在运行。我不知道该怎么做。

+0

这将需要一个LO这是因为索引和表中存在的行数。注意:Varchar(255) – Jauzsika

+0

我认为你应该为它指定一个默认值。可能这就是为什么需要时间? – Nilesh

+1

在这种情况下它默认为'NULL',绝对不是为什么需要很长时间。 – Romain

回答

137

您的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 (fields_in_main_table) SELECT * FROM main_table; 
RENAME TABLE main_table TO main_table_old, main_table_new TO main_table; 
DROP TABLE main_table_old; 

这样你就空表添加列,基本上写在新表,你就一定没有人会是数据没有锁定尽可能多的资源。

+48

+1的'LIKE'语法,我从来没有见过。 – Malvolio

+0

@Malvolio值得注意:我认为这是一个MySQL专有的SQL扩展......尽管如此,并不是100%确定的。 – Romain

+4

即使是这样,上次任何人使用非MySQL SQL RDBMS的时间是?朋友不要让朋友购买Oracle。 – Malvolio

9

我认为这个问题的最佳答案是使用类似pt-online-schema-changegh-ost的功能。

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

Percona的工作在一个非常相似的时装如上

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

这是一个问题,证据表明,较少的投票或接受的解决方案有时是最好的或唯一正确的解决方案。有多少人为OMG不正确的其他解决方案投票。 –