ALTER TABLE ADD COLUMN需要很长时间

fan*_*yna 66 mysql performance alter

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

ALTER TABLE main_table ADD COLUMN location varchar (256);
Run Code Online (Sandbox Code Playgroud)

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

我试图用来mytop 监视这个数据库的活动,以确保查询没有被其他查询过程锁定,但似乎没有.应该花那么长时间吗?实际上,我刚刚在运行此命令之前重启了机器.现在这个命令仍在运行.我不知道该怎么做.

Rom*_*ain 179

您的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;
Run Code Online (Sandbox Code Playgroud)

这样你就可以在空表上添加列,并且基本上在新表中写入数据,你确定没有其他人会在没有锁定那么多资源的情况下查看.

  • 如果您有引用表的外键,这对您没有帮助。 (7认同)
  • 现在动态填写"fields_in_main_table"将是一个在脚本中使用的好东西. (6认同)
  • 即使它是,最后一次使用非MySQL SQL RDBMS的时间是什么时候?朋友不要让朋友买Oracle. (5认同)
  • 即使这种方法虽然必须重写整个表格.我是否认为这种方法的唯一优点是它允许在添加新列期间使用当前表? (4认同)

Pra*_*hra 27

我认为适当的答案是使用像pt-online-schema-changegh-ost这样的功能.

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

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

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

  • 这是一个问题,即证据表明,较少投票或接受的解决方案有时是最好或唯一正确的解决方案.有多少人投票支持另一个不正确的OMG解决方案. (3认同)

Pik*_*er2 8

您可以通过暂时关闭唯一检查和外键检查来加快该过程。您还可以更改使用的算法。

如果您希望新列位于表的末尾,请使用algorithm=instant

SET unique_checks = 0;
SET foreign_key_checks = 0;
ALTER TABLE main_table ADD location varchar(256), algorithm=instant;
SET unique_checks = 1;
SET foreign_key_checks = 1;
Run Code Online (Sandbox Code Playgroud)

否则,如果您需要将该列放置在特定位置,请使用algorithm=inplace

SET unique_checks = 0;
SET foreign_key_checks = 0;
ALTER TABLE main_table ADD location varchar(256) AFTER othercolumn, algorithm=inplace;
SET unique_checks = 1;
SET foreign_key_checks = 1;
Run Code Online (Sandbox Code Playgroud)

作为参考,我的电脑使用就地算法更改具有 2000 万行的表大约需要 2 分钟。如果您使用的是 Workbench 等程序,那么您可能需要在开始操作之前增加设置中的默认超时期限。

如果您发现操作无限期地挂起,那么您可能需要查看进程列表并终止任何在表上拥有锁的进程。您可以使用以下命令来执行此操作:

SHOW FULL PROCESSLIST;
KILL PROCESS_NUMBER_GOES_HERE;
Run Code Online (Sandbox Code Playgroud)