2011-09-18 133 views

回答

6

不幸的是,你可能做得不多。当插入一个新列时,MySQL会复制一张表并在其中插入新数据。您可以发现更快做

CREATE TABLE new_table LIKE old_table; 
ALTER TABLE new_table ADD COLUMN (column definition); 
INSERT INTO new_table(old columns) SELECT * FROM old_table; 
RENAME table old_table TO tmp, new_table TO old_table; 
DROP TABLE tmp; 

这不是我的经验,但我听说别人已经成功。您也可以在插入之前尝试在new_table上禁用索引,然后再重新启用。请注意,在这种情况下,您需要注意不要丢失在转换期间可能插入old_table的任何数据。

或者,如果您的问题在更改过程中影响用户,请检查出pt-online-schema-change,它可以巧妙地使用触发器来执行ALTER TABLE语句,同时保持表格被修改可用。 (请注意,这不会然而加快这一进程。)

+0

小时和等待时间没有做到这一点。最后创建了该表的副本,添加了新列,删除了索引并复制了jiffy –

+0

+1中的记录以获得建议。为我工作,虽然有两个小改变,我会建议。 RENAME new_table TO tmp,old_table TO new_table;应该是 RENAME table new_table TO old_table,old_table TO tmp; – pinaki

+0

@pinaki谢谢。这当然是我的意思。 –

0

迈克尔的解决方案可能会加速一些事情,但也许你应该看看数据库,并尝试将大表分解为更小的表。看看这个:link。规范化数据库表格可能会为您节省将来的时间。

+0

我们在LINUX上使用MySQL,MYISAM。我的意思是在表格中插入一个新类型。 –

+0

这应该真的发布为评论,因为它不回答问题。 –

+0

@coder - 什么让你觉得我的数据库没有正常化? –

1

通常新的行插入意味着有很多索引..所以我会建议重新考虑索引。

+0

是的,我可以删除索引,再次添加新列和重新索引。这会更快,我认为 –

3

有,你可以做,使这个快四个主要方面:

  1. 如果使用innodb_file_per_table原始表可在高度分散文件系统,所以你可以先尝试对它进行碎片整理。

  2. 使缓冲池尽可能大,所以更多的数据,特别是二级索引都适合它。

  3. 使innodb_io_capacity足够高,可能比平常高,这样插入缓冲区合并和修改页面的刷新将更快发生。需要具有InnoDB插件或5.5及更高版本的MySQL 5.1。

  4. 带有InnoDB插件和MySQL 5.5及更高版本的MySQL 5.1支持快速更改表。使得速度更快的事情之一是添加或重建索引,这些索引不是唯一的,也不是外键。所以你可以这样做:

A. ALTER TABLE添加你的列,删除你不是FKs的非唯一索引。

B. ALTER TABLE添加您的非唯一非FK索引。

这应该提供以下好处:

a。步骤A中缓冲池的使用较少,因为缓冲池只需要保存一些索引,即唯一或FK中的索引。在此步骤中索引会随机更新,因此如果它们不能完全适应缓冲池,性能会变得更糟。所以你重建的机会会更快。

b。快速更改表通过对条目进行排序然后构建索引来重建索引。这是更快的,并且还会产生一个页面填充因子较高的索引,因此开始时它会更小更快。

主要的缺点是,这是分两步进行的,在第一步之后,你不会有一些可能需要的索引以获得良好的性能。如果这是一个问题,您可以尝试复制到新的表格方法,首先对新表格使用唯一的FK索引,然后再添加非唯一的索引。

它仅在MySQL 5.6中提供,但http://bugs.mysql.com/bug.php?id=59214中的功能请求提高了插入缓冲区更改刷新到磁盘的速度,并限制了缓冲池可以占用多少空间。这可能是大型工作的性能限制。插入缓冲区用于缓存对二级索引页面的更改。

我们知道,这有时仍然是令人沮丧的缓慢和一个真正的在线修改表非常非常希望

这是我个人的看法。对于Oracle的官方观点,请联系Oracle公关人员。

James Day,MySQL高级主要支持工程师,Oracle