优化mySql以获得更快的alter table add列

时间:2011-04-15 14:04:54

标签: mysql performance alter

我有一个包含170,002,225行的表,其中包含约35列和两个索引。我想添加一个列。 alter table命令大约需要10个小时。在那段时间内,处理器似乎都不忙,也没有过多的IO等待。这是一个带有大量内存的4路高性能盒子。

这是我能做的最好的吗?有什么我可以看一下在调整db时优化add列吗?

5 个答案:

答案 0 :(得分:38)

我过去遇到了类似的情况,我以这种方式改善了操作的性能:

  1. 创建一个新表(使用当前表的结构),其中包含新列。
  2. 执行INSERT INTO new_table (column1,..columnN) SELECT (column1,..columnN) FROM current_table;
  3. 重命名当前表格
  4. 使用当前表的名称重命名新表。

答案 1 :(得分:6)

MySQL中的

ALTER TABLE实际上是用新模式创建一个新表,然后重新INSERT所有数据并删除旧表。您可以通过创建新表,加载数据然后重命名表来节省一些时间。

来自“高性能MySQL书”(percona人):

  

有效加载MyISAM表的常用技巧是禁用密钥,加载数据并插入密钥:

mysql> ALTER TABLE test.load_data DISABLE KEYS;
-- load data
mysql> ALTER TABLE test.load_data ENABLE KEYS;

答案 2 :(得分:3)

也许你可以在更改表之前删除索引,因为构建大部分时间的是索引?

答案 3 :(得分:3)

好吧,我建议使用最新的Percona MySQL版本,因为MySQL手册中有以下注释

  

在其他情况下,MySQL会创建一个   临时表,即使是数据   不会严格要求复制。   对于MyISAM表,您可以加快速度   索引重新创建操作(其中   是改变中最慢的部分   过程)通过设置   myisam_sort_buffer_size系统   变量值很高。

您可以先ALTER TABLE DISABLE KEYS,然后添加列,然后ALTER TABLE ENABLE KEYS。我认为这里无法做任何事情。

顺便说一句,你能不能去MongoDB?添加列时,它不会重建任何内容。

答案 4 :(得分:1)

结合其他答案的一些评论,这是最适合我的解决方案(MySQL 5.6):

  1. create table mytablenew like mytable;
  2. alter table mytablenew add column col4a varchar(12) not null after col4;
  3. alter table mytablenew drop index index1, drop index index2,...drop index indexN;
  4. insert into mytablenew (col1,col2,...colN) select col1,col2,...colN from mytable;
  5. alter table mytablenew add index index1 (col1), add index index2 (col2),...add index indexN (colN);
  6. rename table mytable to mytableold, mytablenew to mytable

在75M的行表上,在插入之前删除索引会导致查询在24分钟而不是43分钟内完成。

其他答案/评论中有insert into mytablenew (col1) select (col1) from mytable,但是如果选择查询中带有括号,则会导致ERROR 1241 (21000): Operand should contain 1 column(s)

其他答案/评论中有insert into mytablenew select * from mytable;,但是如果您已经添加了列,则会得到ERROR 1136 (21S01): Column count doesn't match value count at row 1