为什么在mysql中重命名列需要这么长时间?

14
我有一张大小为12GB的图片表,我正在尝试重命名保存数据的blob列,但这个操作非常耗时。可以有人详细解释一下为什么重命名列需要这么长时间吗?不管表的大小如何,我认为这个操作都应该很快才对啊?
编辑:我运行的查询如下。
 alter table `rails_production`.`pictures` change `data` `image_file_data` mediumblob NULL

看起来大部分时间都花在了等待mysql制作图片表的临时副本上,因为这个表非常大,所以需要一些时间。

将图片存储从数据库更改为文件系统已列入待办事项。

编辑2:Mysql服务器版本:5.0.51a-24+lenny2(Debian)


1
可能把你运行的确切查询发布出来是个好主意。 - nos
1
也许这就是为什么我看到的关于如何在数据库中存储图像的问题通常会说“将图像存储在文件系统中,并在数据库中存储链接到这些图像”。 - pavium
@Janak:你使用的MySQL版本是什么? - outis
3个回答

10

无法详细说明(功能请求#34354可能有所帮助,但它可能不会被反向移植到MySQL 5.0),但额外的时间是由于 ALTER ... CHANGE 可能会更改列的类型(和列属性(如果有)),这需要转换存储在该列中的值和其他检查。 MySQL 5.0没有针对新类型和属性与旧类型相同时的优化。从MySQL 5.0的 ALTER 文档中:

 

在大多数情况下,ALTER TABLE通过创建原始表的临时副本来工作。对副本执行修改,然后删除原始表并将新表重命名。当ALTER TABLE正在执行时,其他会话可以读取原始表。对表格的更新和写入被延迟直至新表准备就绪,然后自动重定向到新表而没有任何失败的更新。

 

[...]

 

如果您使用除RENAME之外的任何选项来ALTER TABLE,则MySQL总是会创建一个临时表,即使数据不需要严格复制(例如更改列的名称)。

在5.1下, ALTER 具有一些额外的优化:

 

在某些情况下,不需要临时表:

 
     
  • 仅修改表元数据而不是表数据的更改可以通过修改表的.frm文件而立即进行,并且不会触及表内容。以下更改是可以通过此方式快速进行的更改:

     
       
    • 重命名列,但不适用于InnoDB存储引擎
    •  
  •  
 

[...]


9
除InnoDB存储引擎之外,更改列名。 :( - pjb3
很好的观点pjb3。不确定自原帖以来是否有所改变,但我编辑了答案以反映MySQL文档。正如你所说,这种技术似乎不支持innodb。 - DougW
我知道您在2010年发布了这个答案,但是自那时以来,MySQL 5.6已经增加了很多新的情况,可以使用原地ALTER。请参见http://dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl.html。 - Bill Karwin

7
因为MySQL在进行模式更改时会重建整个表格。
这样做是因为在某些情况下这是唯一的方法,并且这样做可以使服务器更轻松地重建它。

2

是的,mysql会对表进行临时复制。我不认为有简单的方法可以解决这个问题。你应该考虑将图片存储在文件系统中,只在mysql中存储路径。这是加速的唯一方法,我想。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接