MySQL5.7 线上常用的DDL的性能测试

测试环境:2核4G Intel® Xeon® Gold 6138 CPU @ 2.00GHz

测试表初始结构:
CREATE TABLE t1 (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(20) COLLATE utf8mb4_bin DEFAULT NULL,
score int(11) DEFAULT NULL,
PRIMARY KEY (id),
KEY score (score)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin

数据量:200W条
测试内容:字段添加修改删除的RT值,索引添加删除、更名的RT值,以及以上两部分的数据读写阻塞情况(锁的情况);varcahr字段增长&变短(256阈值的测试。经测试要9.01 sec)
测试准备:直接cp备份数据目录,以便还原初始环境。

----在DDL开始之前,当DDL的操作的大表有事务在DML操作(包括读),则会产生锁等待,这是由于MDL的原因,防止在进行DML操作时表结构被修改(包括索引),从而发生数据读取不一致或者其他问题。

1.添加字段
alter table t1 add column sex char(1) not null comment ‘性别’;
4.43 sec
并且当陆续增加字段时,RT值越来越大,因为表的物理大小越来越大,而在mysql5.7中,加字段的修改是会在库的目录操作,建立一个隐藏的表,
然后把导入进来,在ddl过程中产生的dml会存于一个缓冲地区,待原表数据导入完成后,会给原表上写锁,然后把缓冲的修改导入到隐藏的表中,然后删除原表rename新表回原表的名字

2.删除字段
alter table t1 drop column score;
5.04 sec

3.修改数据类型
alter table t1 modify column score varchar(20);
12.79 sec

4.修改varchar类型长度问题
增大到256以下的值如20到25
测试结果:毫秒级别
减少长度
测试结果:根据数据量的多少来决定速度,200W大约9 sec
增加到256以上的值
测试结果:根据数据量的多少来决定速度,200W大约9 sec

5.修改列名
alter table t1 change column name1 new_name char(10);
a.当只修改列的名称时毫秒级别。
b.当修改名称且修改数据类型时,根据列的数据大小决定速度。
c.当修改列名及数据类型时,是varchar类型时,要是增大长度(不超过256/4=64的值(4是因为用的utf8mb4)),则较快(200W要2 sec),不用影子表,否则要需要影子表机制(200W要12 sec)

6.添加索引
alter table t1 add index fenshu (fenshu);
3.12 sec

7.删除索引
alter table t1 drop index fenshu;
0.02 sec

8.修改索引名字
alter table t1 rename index fenshu to idx_fenshu;
0.01 sec


另外发现修改数据类型时varcahr到int转快一些,int到varchar慢一些;

总结:
经查阅资料,现在总结上面的实验结果。5.7版本的mysql,在添加或者删除字段时,执行时间跟表的物理大小相关,MYSQL内部的执行机制如下:

  1. 建立新的表(库中不可见,俗称影子表),同时开始旧表中的数据导入新表
  2. 旧表的DML操作不阻塞,因为数据写入innodb_online_alter_log_max_size的buffer中。
  3. 在旧表的数据完全导入影子表自中后,给旧表上写锁,然后把buffer中新增的数据写入到影子表中
  4. 删除旧表,rename影子表为旧表名称,解开锁。Done

可虽然说是onlineDDL,但是会COPY表,等于表的物理大小会扩大一倍,对于大表操作一定要小心了,确保磁盘够用!!!在修改列的类型,除开varchar字段的变长不超过255的情况下,都是会出现上面那种情况。删除索引,索引更名,都是极快的,新增索引速度根据表的大小来决定。

你可能感兴趣的:(技术)