Mysql 除了并行查询以外也可以并行索引,升级吧少年

af0d5ed94d8e13e2f2081f68d00a0d22.png

POSTGRESQL 在 DDL DML DQL 都可以并行,之前MYSQL 在并行方面一直是软肋,MYSQL 8 已经提供了DQL的并行, DDL 的并行也支持了,从MYSQL5.X 升级到8 是必然了.

注意版本必须是8.027 ,对写这篇文字的MYSQL 最新的可以工作的版本。

首先我们先要弄清楚到底那些操作会使用DDL 并行的操作, 

1 索引操作

2 主键操作

3 column 字段的操作

4 分区表,表空间,表的维护操作

针对索引的操作本身只有全文索引和空间索引是不能使用并行的能力

OperationInstantIn PlaceRebuilds TablePermits Concurrent DMLOnly Modifies Metadata
Creating or adding a secondary indexNoYesNoYesNo
Dropping an indexNoYesNoYesYes
Renaming an indexNoYesNoYesYes
Adding a FULLTEXT indexNoYes*No*NoNo
Adding a SPATIAL indexNoYesNoNoNo
Changing the index typeYesYesNoYesYes

下面以添加索引为例,这里需要引入 8.027 的新参数 innodb-ddl-threads,

那么为什么索引的并行操作能提高添加索引的效率,原理也很简单

在添加二级索引的时候,我们需要

1 扫描clustered index  并将数据存储都临时表中

2 针对这些数据进行排序

3 加载排序的数据从临时文件,写入到二级索引中

与并行索引工作有关的参数

1  扫描聚集索引(主键)的并行数由 innodb_parallel_read_threads 来决定,默认设置为4, 具体以cpu的核心数 - 2 到 8 来设置。 但需要注意的是即使设置了,如果无法使用并行,系统还会使用单核心的方式运行。

2  在创建并行索引是,需要注意对于并行的线程分配内存 在8.027上新添加了 innodb_ddl_buffer_size  参数,内存具体在每个线程上的使用是 innodb_ddl_buffer_size / innodb_ddl_threads 

参数默认大小 1MB

0eb14f882e78a6fc1ca70934302a4961.png

3  innodb_online_alter_log_max_size 这个设置主要针对进行DDL操作时的临时空间的设置,默认128MB ,在索引操作时,会将读取的数据写入临时文件,临时文件的尺寸由innodb_online_alter_log_max  决定。

69e148d6bf92857007d60f3f0f866cf4.png

4   innodb_sort_buffer_size 在操作二级索引建立时需要对临时的文件的内容进行排序,就需要innodb_sort_buffer_size 来控制缓存。

5  innodb_tmpdir 临时对alter table 的语句中存储的临时数据目录的磁盘空间不足也会导致操作失败

e73799a254b81452b9017d8d8e7c8a7b.png

我们来对并行添加索引的参数和速度进行一个比较。

CREATE TABLE `t_user` (

  `id` bigint(20) NOT NULL AUTO_INCREMENT,

  `name` varchar(255) DEFAULT NULL,

  `age` tinyint(4) DEFAULT NULL,

  `create_time` datetime DEFAULT NULL,

  `update_time` datetime DEFAULT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

delimiter $$

DROP PROCEDURE IF EXISTS proc_batch_insert;

CREATE PROCEDURE proc_batch_insert()

BEGIN

DECLARE pre_name BIGINT;

DECLARE ageVal INT;

DECLARE i INT;

SET pre_name=187635267;

SET ageVal=100;

SET i=1;

WHILE i < 1000000 DO

INSERT INTO t_user(`name`,age,create_time,update_time) VALUES(CONCAT(pre_name,'@qq.com'),(ageVal+i)%30,NOW(),NOW());

SET pre_name=pre_name+100;

SET i=i+1;

END WHILE;

END $$

delimiter ;

我们建立一个t_user表,并在表里添加100万的数据

然后我们我们先添加索引,

1  不调节任何参数,时间为3.68秒

2  调整DDL 操作的buffer 加大到目前的默认的配置的8倍

     在添加索引时间变为 2.93秒

3  将并行开到 8 在建立索引, 时间为2.78秒

4  将并行关闭,在建立所以,建立时间为3.41秒

通过上面的参数调节我们可以看到,不同的参数的变化对于添加索引的性能影响,加大 innodb_ddl_buffer_size 和 innodb_parallel_read_threads  对索引的建立的速度提升有很大的帮助。

afb2b74e6149ebfea5507534fffb4633.png

另外 MYSQL 8.027 引入了 innodb_ddl_threads 参数这个参数主要针对索引建立时的排序和建立阶段,同时也会应用到rebuild secondrary indexes 的操作中,默认值 4 , 可以设置的值从1 -64 ,对于MYSQL 使用多核心CPU越来越有意义。

bcd1757fca6a50f6277a69a26c2773c8.png

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值