一.初步获得思路 Mysql批量插入100W条数据的开发思路
1.测试单条插入和批量插入,分析插入性能瓶颈在那里
2.测试单次传输的数据量大小对性能的影响。比如单次传输的数据量是5000条,1W条,5W条,10W条
3.测试批量插入数据在单线程执行和并发执行的性能对比,从10个线程->20->40个线程,为什么后面线程数越来越多,反而速度更慢了,性能瓶颈究竟卡在那了
关键思考点:罗列主要的性能影响因素,通过测试实践发现性能瓶颈究竟卡在那了,是CPU核数,网络io还是数据库本身是性能瓶颈
二.批量插入数据的性能影响因素 1.并发性对批量插入数据的性能影响 2.网络IO资源,比如建立多少次数据库连接,传输带宽等因素 3.数据库方面,比如SQL语句,数据库配置等等 4.磁盘io
测试过程与方法概述
1. 测试目标
测试的主要目标是评估不同条件下数据插入操作的性能,包括单条插入、批量插入,以及多线程+批量插入的效果。通过这些测试,了解在大数据量场景下,如何优化插入操作以提高性能。
2. 测试环境
测试的执行环境是一个标准化的数据库和应用服务器,假设这些测试是在相对独立的环境中进行,且数据库系统的配置、硬件条件、网络带宽等因素保持一致。测试数据量从1,000条到1,000万条不等,测试的数据库是关系型数据库(如MySQL)。
测试过程
1. 单条插入测试
-
测试方法:直接使用循环的方式一条一条地向数据库插入数据。
-
测试步骤:
- 准备1,000条、10,000条、100,000条、1,000,000条、10,000,000条数据。
- 使用JDBC或其他数据库访问接口,单条执行
INSERT INTO
语句,将数据插入到数据库中。 - 记录不同数据量下操作的时间,单位为秒(s)。
-
测试结果:
- 1,000条数据:4.3秒
- 10,000条数据:28.28秒
- 100,000条数据:250.18秒
- 1,000,000条和10,000,000条因时间限制未测试。
2. 批量插入测试
-
测试方法:使用数据库的批量插入功能,将多条数据一次性插入数据库。
-
测试步骤:
- 准备相同数量的数据(1,000条、10,000条、100,000条、1,000,000条、10,000,000条)。
- 使用批量插入的方式(例如:
INSERT INTO table_name (columns) VALUES (value1), (value2), ...
)批量插入数据到数据库。 - 分别测试不同数据量和不同批次大小的插入操作。
- 记录操作时间。
-
测试结果:
- 1,000条数据:1.25秒
- 10,000条数据:3.05秒
- 100,000条数据:17.04秒
- 1,000,000条数据:144秒
- 10,000,000条数据:1,479秒(接近25分钟)
3. 批量插入测试中的批量大小(batch size)影响
-
测试方法:在批量插入的基础上,调整一次性插入的数据条数(即批量大小)。
-
测试步骤:
- 对于相同的数据总量(如1,000,000条),测试不同的批量大小:1,000条、10,000条、100,000条。
- 观察批量大小对插入时间的影响。
-
测试结果:
- 数据量1,000,000条,批量大小1,000:132秒
- 数据量1,000,000条,批量大小10,000:130秒
- 数据量1,000,000条,批量大小100,000:111秒
4. 多线程 + 批量插入测试
-
测试方法:通过使用多线程并发插入数据的方式,结合批量插入功能,以进一步优化插入性能。
-
测试步骤:
- 将数据分成多个线程,并发执行插入操作。每个线程执行固定大小的批量插入。
- 固定每次批量插入的数据量为10,000条,分别使用5个、10个、15个、20个线程执行插入操作。
- 记录不同线程数下的插入时间。
-
测试结果:
- 5个线程:43秒
- 10个线程:42秒
- 15个线程:35秒
- 20个线程:36秒
单条插入性能测试
插入条数 | 时间(秒) |
---|---|
1000 | 4.3 |
1w | 28.2850132 |
10w | 250.1833812 |
100w | 未测试 |
1000w | 未测试 |
批量插入性能测试
插入条数 | 批量插入时间(秒) |
---|---|
1000 | 1.25 |
1w | 3.05 |
10w | 17.04 |
100w | 144 |
1000w | 1479(约25分钟) |
批量插入不同一次传输数据量性能测试
插入数据量 | 一次传输数据量 | 时间(秒) |
---|---|---|
1w | 1w | 3.05 |
10w | 1w/10w | 17.2s/17.04s |
100w | 1k/1w/10w/100w | 132s/130s/111s/130s |
1000w | 1w/10w/100w | 2083s(约34分钟) |
多线程+批量插入性能测试
线程数 | 批量插入时间(秒) |
---|---|
5 | 43 |
10 | 42 |
15 | 35 |
20 | 36 |
多线程+批量插入不同batchSize性能测试
一次传输数据量 | 时间(秒) |
---|---|
1k | 27 |
1w | 42 |
10w | 48 |
性能提升与分析
-
单条插入 vs 批量插入:
- 批量插入相比单条插入性能显著提高。以10,000条数据为例,批量插入只需3.05秒,而单条插入则需要28.28秒。批量插入利用了数据库的批处理能力,减少了网络开销和事务管理的负担。
-
批量大小的影响:
- 批量大小对性能有一定影响,但并非越大越好。对于1,000,000条数据的插入,当批量大小为100,000条时,性能最好(111秒)。这说明在批量插入时需要找到一个适当的批次大小,既能充分利用批处理,又不至于因为单次处理的数据量过大而导致性能下降。
-
多线程批量插入的效果:
- 多线程结合批量插入进一步提升了性能。例如,在使用10个线程时,批量大小10w,插入100万条数据只需42秒。相比单线程批量插入的130秒,多线程批量插入可以减少插入时间超过60%。
总结
通过上述测试,可以得出以下结论:
- 批量插入显著优于单条插入。
- 批量插入的性能与批次大小有关,选择合适的批次大小可以优化性能。
- 多线程结合批量插入是进一步提升插入性能的有效手段,在大数据量插入场景下尤为明显。
最慢的方式是使用单条插入方式插入 100w 条数据,需要大约 250.18 秒。
最快的方式是10 个线程,每次传输 1k 条数据 时,插入 100w 条数据,为 27 秒。
性能提升约89.2%
四.实践结论
1.批量插入远比单条插入的性能要高得多,是几十倍的性能提升
2.批量插入的数据量大小如何确定,通过一次次调整批量插入的数据量大小对性能影响,最终得出一个性能较高的数据量大小。但带宽对性能影响不是很大,可能就是8/1-10/1的优化吧
小解读:带宽越大,需要建立的数据连接越少,所以关于网络带宽和数据库连接要综合考虑以及多次测试才能得出一个恰当的数据
小tips:极限值是数据库连接资源最大化利用 带宽资源最大化利用,当然千万不要在生产环境这样弄,上来就占用那么多资源,其他需要资源的功能怎么办,而且推荐测试循序渐进,数据量逐渐增多,可以及早发现的问题,不然一上来数据量就这么大,问题一出就会很严重
3.多线程(线程池) 批量插入。线程池中的核心线程数,最大线程数应如何确定? 关于核心线程数,最大线程数如何确定的问题,这里借美团技术团队的文章来浅答以下(我自己的水平有限) 通过阅读美团技术团队对线程池参数的解读,发现线程池的参数是很难有一个标准答案,不同的业务差异是非常大的,不同的任务类型差距业非常大,所以美团选择了一个折中的方案,就是动态化 实时监控线程池的状态,根据实际业务状况实时调整线程池的参数
4.确定了线程池的核心参数后,那么业务实际分配的线程数又该如何确定呢?
学到的思路就是不断的测试,实践才能得到真知,线程数,数据量逐渐增大,每个层级的线程数和数据量进行测试,当经过了大量的测试后,得到一个较为恰当的答案应该是没问题的 实验中的测试案例 其实你会发现多线程到15个的时候,无论再怎么增加线程数,性能都不会有多大变化,证明性能的瓶颈到了,且瓶颈不是线程数的问题,也不是数据库连接数的问题了(因为已经用批量插入优化了,也测试过了),很有可能就是数据库同一时刻只能处理这么多插入数据,是数据库本身的性能瓶颈到了,但是多线程对比单线程性能是足足提高了50%-60%,至于业务实际要分配多少个线程数,我想没什么比实践的结果来得更可靠,一次一次测试,直到得到最恰当的数值,自然就是业务所需的实际线程数分配了