简体   繁体   English

优化 mySql 以更快地更改表添加列

[英]Optimize mySql for faster alter table add column

I have a table that has 170,002,225 rows with about 35 columns and two indexes.我有一个表,它有 170,002,225 行,大约有 35 列和两个索引。 I want to add a column.我想添加一列。 The alter table command took about 10 hours. alter table 命令花费了大约 10 个小时。 Neither the processor seemed busy during that time nor were there excessive IO waits.在此期间,处理器似乎并不忙,也没有过多的 IO 等待。 This is on a 4 way high performance box with tons of memory.这是一个带有大量内存的 4 路高性能盒子。

Is this the best I can do?这是我能做的最好的吗? Is there something I can look at to optimize the add column in tuning of the db?有什么我可以看的东西来优化数据库调整中的添加列吗?

I faced a very similar situation in the past and i improve the performance of the operation in this way :我过去遇到过非常相似的情况,我以这种方式提高了操作的性能:

  1. Create a new table (using the structure of the current table) with the new column(s) included.创建一个包含新列的新表(使用当前表的结构)。
  2. execute a INSERT INTO new_table (column1,..columnN) SELECT (column1,..columnN) FROM current_table;执行INSERT INTO new_table (column1,..columnN) SELECT (column1,..columnN) FROM current_table;
  3. rename the current table重命名当前表
  4. rename the new table using the name of the current table.使用当前表的名称重命名新表。

ALTER TABLE in MySQL is actually going to create a new table with new schema, then re- INSERT all the data and delete the old table. MySQL中的ALTER TABLE实际上是要创建一个具有新模式的新表,然后重新INSERT所有数据并删除旧表。 You might save some time by creating the new table, loading the data and then renaming the table.您可以通过创建新表、加载数据然后重命名表来节省一些时间。

From "High Performance MySQL book" (the percona guys):来自“高性能 MySQL 书”(percona 人):

The usual trick for loading MyISAM table efficiently is to disable keys, load the data and renalbe the keys:有效加载 MyISAM 表的常用技巧是禁用键、加载数据和肾为键:

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

Well, I would recommend using latest Percona MySQL builds plus since there is the following note in MySQL manual好吧,我建议使用最新的 Percona MySQL 版本,因为 MySQL 手册中有以下说明

In other cases, MySQL creates a temporary table, even if the data wouldn't strictly need to be copied.在其他情况下,即使数据并不严格需要复制,MySQL 也会创建一个临时表。 For MyISAM tables, you can speed up the index re-creation operation (which is the slowest part of the alteration process) by setting the myisam_sort_buffer_size system variable to a high value.对于 MyISAM 表,您可以通过将 myisam_sort_buffer_size 系统变量设置为高值来加快索引重新创建操作(这是更改过程中最慢的部分)。

You can do ALTER TABLE DISABLE KEYS first, then add column and then ALTER TABLE ENABLE KEYS .您可以先执行ALTER TABLE DISABLE KEYS ,然后添加列,然后ALTER TABLE ENABLE KEYS I don't see anything can be done here.我看不到这里可以做任何事情。

BTW, can't you go MongoDB?顺便说一句,你不能去MongoDB吗? It doesn't rebuild anything when you add column.添加列时它不会重建任何内容。

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

Combining some of the comments on the other answers, this was the solution that worked for me (MySQL 5.6):结合对其他答案的一些评论,这是对我有用的解决方案(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

On a 75M row table, dropping the indexes before the insert caused the query to complete in 24 minutes rather than 43 minutes.在一个 75M 的行表上,在插入之前删除索引导致查询在 24 分钟而不是 43 分钟内完成。

Other answers/comments have insert into mytablenew (col1) select (col1) from mytable , but this results in ERROR 1241 (21000): Operand should contain 1 column(s) if you have the parenthesis in the select query.其他答案/评论已insert into mytablenew (col1) select (col1) from mytable ,但这会导致ERROR 1241 (21000): Operand should contain 1 column(s) if you have the parenthesis in the select query.

Other answers/comments have insert into mytablenew select * from mytable;其他答案/评论已insert into mytablenew select * from mytable; , but this results in ERROR 1136 (21S01): Column count doesn't match value count at row 1 if you've already added a column. ,但这会导致ERROR 1136 (21S01): Column count doesn't match value count at row 1如果您已经添加了一列,则列ERROR 1136 (21S01): Column count doesn't match value count at row 1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM