1000000条数据同时插入! 强大的Mysql数据库是这样运作的!真是没想到 !

可莉
• 阅读 665

点击上方“Java研发军团”关注,选择“设为星标”

回复“1024”获取持续更新Java架构师资料

目录

1、多线程插入(单表)
2、多线程插入(多表)
3、预处理SQL
4、多值插入SQL
5、事务(N条提交一次)

多线程插入(单表)

问:为何对同一个表的插入多线程会比单线程快?同一时间对一个表的写操作不应该是独占的吗?

答:在数据里做插入操作的时候,整体时间的分配是这样的:

1、多链接耗时 (30%) 

2、多发送query到服务器 (20%) 

3、多解析query (20%) 

4、多插入操作 (10% * 词条数目) 

5、多插入index (10% * Index的数目)

6、多关闭链接 (10%)

从这里可以看出来,真正耗时的不是操作,而是链接,解析的过程。

MySQL插入数据在写阶段是独占的,但是插入一条数据仍然需要解析、计算、最后才进行写处理,比如要给每一条记录分配自增id,校验主键唯一键属性,或者其他一些逻辑处理,都是需要计算的,所以说多线程能够提高效率。

多线程插入(多表)

分区分表后使用多线程插入。

预处理SQL

普通SQL:**** 即使用Statement接口执行SQL

预处理SQL:**** 即使用PreparedStatement接口执行SQL

使用PreparedStatement接口允许数据库预编译SQL语句,以后只需传入参数,避免了数据库每次都编译SQL语句,因此性能更好。

  1. String sql = "insert into testdb.tuser (name, remark, createtime, updatetime) values (?, ?, ?, ?)";

  2. for(int i = 0; i < m; i++) {

  3. //从池中获取连接

  4. Connection conn = myBroker.getConnection();

  5. PreparedStatement pstmt = conn.prepareStatement(sql);

  6. for(int k = 0; k < n; k++) {

  7. pstmt.setString(1, RandomToolkit.generateString(12));

  8. pstmt.setString(2, RandomToolkit.generateString(24));

  9. pstmt.setDate(3, newDate(System.currentTimeMillis()));

  10. pstmt.setDate(4, newDate(System.currentTimeMillis()));

  11. //加入批处理

  12. pstmt.addBatch();

  13. }

  14. pstmt.executeBatch(); //执行批处理

  15. pstmt.close();

  16. myBroker.freeConnection(conn); //连接归池

  17. }

多值插入SQL

普通插入SQL:INSERT INTO TBL_TEST (id) VALUES(1)

多值插入SQL:INSERT INTO TBL_TEST (id) VALUES (1), (2), (3)

使用多值插入SQL,SQL语句的总长度减少,即减少了网络IO,同时也降低了连接次数,数据库一次SQL解析,能够插入多条数据。

事务(N条提交一次)

在一个事务中提交大量INSERT语句可以提高性能。

1、将表的存储引擎修改为myisam 2、将 sql 拼接成字符串,每 1000 条左右提交事务。

  • 执行多条SQL语句,实现数据库事务。

  • mysql数据库

  • 多条SQL语句

  1. public void ExecuteSqlTran(List<string> SQLStringList)

  2. {

  3. using (MySqlConnection conn = new MySqlConnection(connectionString))

  4. {

  5. if (DBVariable.flag)

  6. {

  7. conn.Open();

  8. MySqlCommand cmd = new MySqlCommand();

  9. cmd.Connection = conn;

  10. MySqlTransaction tx = conn.BeginTransaction();

  11. cmd.Transaction = tx;

  12. try

  13. {

  14. for (int n = 0; n < SQLStringList.Count; n++)

  15. {

  16. string strsql = SQLStringList[n].ToString();

  17. if (strsql.Trim().Length > 1)

  18. {

  19. cmd.CommandText = strsql;

  20. cmd.ExecuteNonQuery();

  21. }

  22. //后来加上的

  23. if (n > 0 && (n % 1000 == 0 || n == SQLStringList.Count - 1))

  24. {

  25. tx.Commit();

  26. tx = conn.BeginTransaction();

  27. }

  28. }

  29. //tx.Commit();//原来一次性提交

  30. }

  31. catch (System.Data.SqlClient.SqlException E)

  32. {

  33. tx.Rollback();

  34. throw new Exception(E.Message);

  35. }

  36. }

  37. }

  38. }

10w条数据大概用时10s!

原文:https://blog.csdn.net/qq\_36691683/article/details/89297261

参考资料:

https://www.cnblogs.com/aicro/p/3851434.html

http://blog.jobbole.com/29432/

1000000条数据同时插入! 强大的Mysql数据库是这样运作的!真是没想到 !

1000000条数据同时插入! 强大的Mysql数据库是这样运作的!真是没想到 !

本文分享自微信公众号 - Java研发军团(ityuancheng)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
Python3:sqlalchemy对mysql数据库操作,非sql语句
Python3:sqlalchemy对mysql数据库操作,非sql语句python3authorlizmdatetime2018020110:00:00coding:utf8'''
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
3年前
Docker 部署SpringBoot项目不香吗?
  公众号改版后文章乱序推荐,希望你可以点击上方“Java进阶架构师”,点击右上角,将我们设为★“星标”!这样才不会错过每日进阶架构文章呀。  !(http://dingyue.ws.126.net/2020/0920/b00fbfc7j00qgy5xy002kd200qo00hsg00it00cj.jpg)  2
Stella981 Stella981
3年前
1000000条数据同时插入! 强大的Mysql数据库是这样运作的!真是没想到 !
点击上方“Java研发军团”关注,选择“设为星标”回复“1024”获取持续更新Java架构师资料目录1、多线程插入(单表)2、多线程插入(多表)3、预处理SQL4、多值插入SQL5、事务(N条提交一次)多线程插入(单表)问:为
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究