我在本地安装了InnoDB的MySQL 5.5.37和Ubuntu 13.10上的apt-get。我的机器是台式机上的i7-3770 + 32Gb内存+ SSD硬盘。对于只包含150万条记录的“mytable”表,以下DDL查询需要超过20分钟(!):
ALTER TABLE mytable ADD some_column CHAR(1) NOT NULL DEFAULT 'N';
有没有办法改善它? 我查了一下
show processlist;
并且它显示出由于某种原因它正在复制我的表。 令人不安的是令人不安的。有没有办法关掉这个副本? 是否有其他方法可以提高将列添加到大型表的性能?
除此之外,我的数据库相对较小,只有1.3Gb转储大小。因此它(理论上)应该100%适合记忆。
是否有可以提供帮助的设置? 迁移到Precona会改变我的一切吗?
添加:我有
innodb_buffer_pool_size = 134217728
答案 0 :(得分:13)
是否有其他方法可以提高将列添加到大型表的性能?
简答:不。您可以立即添加ENUM和SET值,并且可以在仅锁定写入时添加二级索引,但是更改表结构始终需要表副本。
答案很长:你真正的问题不是真正的表现,而是锁定时间。如果它很慢并不重要,只有在ALTER TABLE完成之后其他客户端才能执行查询。在这种情况下有一些选择:
您可以使用Percona工具包中的pt-online-schema-change。先备份您的数据!这是最简单的解决方案,但可能无法在所有情况下都有效。
如果您不使用外键并且因为您有很多索引而速度很慢,那么使用您需要的更改来创建表的副本可能会更快,但是没有二级索引,请填充它使用数据,并在末尾使用单个alter table创建所有索引。
如果你很容易创建副本,就像你在Amazon RDS上托管一样,你可以创建一个主 - 主副本,在那里运行alter table,让它恢复同步,并切换实例完成后。
<强>更新强>
正如其他人提到的,MySQL 8.0 INNODB增加了对即时列添加的支持。它不是一个神奇的解决方案,它有局限性和副作用 - 它只能是最后一列,表格不能有全文索引等 - 但在许多情况下应该有所帮助。
您可以指定显式ALGORITHM=INSTANT LOCK=NONE
参数,如果无法立即更改模式,MySQL将失败并返回错误,而不是回退到INPLACE
或COPY
。例如:
ALTER TABLE mytable
ADD COLUMN mycolumn varchar(36) DEFAULT NULL,
ALGORITHM=INPLACE, LOCK=NONE;
https://mysqlserverteam.com/mysql-8-0-innodb-now-supports-instant-add-column/
答案 1 :(得分:4)
MariaDb 10.3,MySQL 8.0以及可能跟随的其他MySQL变体都有一个&#34; Instant ADD COLUMN&#34;功能,大多数列(有一些约束,请参阅文档)可以立即添加,没有表重建。
答案 2 :(得分:2)
在线DDL怎么样?
http://www.tocker.ca/2013/11/05/a-closer-look-at-online-ddl-in-mysql-5-6.html
也许您会使用TokuDB:
答案 3 :(得分:1)
由于结构发生变化,因此无法在添加或删除列时避免复制表。您可以在没有表副本的情况下添加或删除辅助索引。
您的表格数据不会驻留在内存中。索引可以驻留在内存中。
150万条记录不是很多行,20分钟看起来很长,但也许你的行很大而且你有很多索引。
在复制表格时,您仍然可以从表格中选择行。但是,如果您尝试进行任何更新,它们将被阻止,直到ALTER
完成。
答案 4 :(得分:0)
我知道这是一个比较老的问题,但是今天我遇到了类似的问题。我决定创建一个新表并将旧表导入新表中。像这样:
CREATE TABLE New_mytable LIKE mytable ;
ALTER TABLE New_mytable ADD some_column CHAR(1) NOT NULL DEFAULT 'N';
insert into New_mytable select * from mytable ;
然后
START TRANSACTION;
insert into New_mytable select * from mytable where id > (Select max(id) from New_mytable) ;
RENAME TABLE mytable TO Old_mytable;
RENAME TABLE New_mytable TO mytable;
COMMIT;
这不会使更新过程进行得更快,但是可以最大程度地减少停机时间。
希望这会有所帮助。