MySQL一次性添加多列耗时久,拆分操作或调整默认值能否提速?
MySQL大表加列速度优化方案
通用提速方法
- 尽量在业务低峰期执行操作,避免行锁、表锁和业务读写请求互相阻塞
- 如果你使用的是MySQL 5.6及以上版本,优先在ALTER语句中加
ALGORITHM=INPLACE, LOCK=NONE参数,避免全表拷贝和全程锁表,语法参考:
ALTER TABLE `exes` ADD COLUMN `p` TINYINT(4) DEFAULT 5 AFTER `executed`, ADD COLUMN `executed_query` LONGTEXT AFTER `p`, ALGORITHM=INPLACE, LOCK=NONE;
- 操作前先检查数据库中有没有未提交的长事务、正在运行的其他DDL操作,长事务会阻塞ALTER执行,导致全程锁表拉长耗时
- 如果是超大规模的表,可以考虑用pt-online-schema-change、gh-ost这类在线变更工具执行操作,避免长时间锁表影响业务
- 执行变更前务必先备份表数据,避免操作出错导致数据丢失
疑问解答
1. 我是否应该每次仅给一个表添加一列,而非一次性添加多列?
不需要拆分。同一张表一次性添加多列的性能远好于分开多次执行ALTER操作:MySQL执行单次ALTER的时候只需要扫描/改写一次表,拆成多次会重复执行多次全表操作,反而会大幅增加总耗时。你现在写的同一条ALTER语句里加两个列的写法是合理的,不需要拆分。
2. 给列设置DEFAULT 5的默认值是否会拖慢schema更新的速度?
分MySQL版本判断:
- MySQL 8.0之前的版本,添加带DEFAULT值的列如果需要走表拷贝逻辑(ALGORITHM=COPY),需要逐行给新列填充默认值,确实会增加耗时;
- MySQL 8.0及以上版本支持了立即加列特性,添加带默认值的固定长度列(比如你使用的TINYINT)不需要逐行更新,只会修改表的元数据,瞬间就能完成,不会拖慢速度。
另外你添加的LONGTEXT是可变长度类型,不管有没有设置默认值,都不会修改原有行的数据,对操作速度的影响很小。
内容的提问来源于stack exchange,提问作者BAE
相关产品推荐
相关产品推荐

