Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql ALTER TABLE ADD COLUMN需要很长时间_Mysql_Performance_Alter - Fatal编程技术网

Mysql ALTER TABLE ADD COLUMN需要很长时间

Mysql ALTER TABLE ADD COLUMN需要很长时间,mysql,performance,alter,Mysql,Performance,Alter,我只是想在数据库的一个表(main_table)中添加一个名为“location”的列。我运行的命令是 ALTER TABLE main_table ADD COLUMN location varchar (256); 主_表包含>2000000行。它持续运行超过2小时,但仍未完成 我尝试使用mytop 监视此数据库的活动,以确保查询未被其他查询进程锁定,但似乎未被锁定。要花那么长时间吗?实际上,我只是在运行这个命令之前重新启动了机器。现在该命令仍在运行。我不知道该怎么办 您的altertab

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

ALTER TABLE main_table ADD COLUMN location varchar (256);
主_表包含>2000000行。它持续运行超过2小时,但仍未完成

我尝试使用
mytop

监视此数据库的活动,以确保查询未被其他查询进程锁定,但似乎未被锁定。要花那么长时间吗?实际上,我只是在运行这个命令之前重新启动了机器。现在该命令仍在运行。我不知道该怎么办

您的
altertable
语句意味着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;

通过这种方式,您可以在空表上添加列,并基本上在新表中写入数据,您可以确定,如果不锁定那么多资源,其他人将不会看到这些数据。

我认为适当的答案是使用类似或的功能

我们已经用它完成了超过40亿行的迁移,尽管它最多需要10天,停机时间不到一分钟

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

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

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;

这将需要很长时间,因为表中存在索引和行数。注意:Varchar(255)我想您应该为它指定一个默认值。可能这就是它需要时间的原因?在这种情况下,它默认为
NULL
,这绝对不是它需要很长时间的原因。MySQL 8.0.12有一个
ALTER表。。添加列。。ALGORITHM=INSTANT
@Malvolio值得注意的是:我认为它是MySQL专有的SQL扩展。。。尽管不是100%确定。即使是,上一次有人使用非MySQL SQL RDBMS是什么时候?朋友不允许朋友购买Oracle。现在动态填写“fields\u in\u main\u table”对于脚本来说是一件很好的事情。尽管这种方法必须重写整个表。我认为这种方法的唯一优点是允许在添加新列的过程中使用当前表,对吗?如果您有外键引用表,这对您没有帮助。这类问题证明,投票次数少或被接受的解决方案有时是最佳或唯一正确的解决方案。有多少人投票支持另一个不正确的解决方案?天哪。@RaulR。这取决于用例。另一个解决方案在我的用例中非常“正确”,并不是每个人都在24/7生产环境中工作。请注意,pt在线模式更改实际上可能会导致阻塞表。如果您的大表中有指向它的fks,则可能有阻塞时间或丢失fks。您需要选择一个
alter foreign keys方法
rebuild\u约束
将需要重新构建fk,这将阻止引用表。