点击上方“Java基基”,选择“设为星标”
做积极的人,而不是积极废人!
源码精品专栏
来源:juejin.im/post/5d255ab9e51d454f73356dcd
大家好,我是基基!
问:为何对同一个表的插入多线程会比单线程快?同一时间对一个表的写操作不应该是独占的吗?
答:在数据里做插入操作的时候,整体时间的分配是这样的:
从这里可以看出来,真正耗时的不是操作,而是链接,解析的过程。
MySQL插入数据在写阶段是独占的,但是插入一条数据仍然需要解析、计算、最后才进行写处理,比如要给每一条记录分配自增id,校验主键唯一键属性,或者其他一些逻辑处理,都是需要计算的,所以说多线程能够提高效率。
分区分表后使用多线程插入。
使用PreparedStatement接口允许数据库预编译SQL语句数据库插入操作,以后只需传入参数,避免了数据库每次都编译SQL语句,因此性能更好。
String?sql?=?"insert?into?testdb.tuser?(name,?remark,?createtime,?updatetime)?values?(?,??,??,??)"; for?(int?i?=?0;?i?<?m;?i++)?{ ????//从池中获取连接 ????Connection?conn?=?myBroker.getConnection(); ????PreparedStatement?pstmt?=?conn.prepareStatement(sql); ????for?(int?k?=?0;?k?<?n;?k++)?{ ????????????pstmt.setString(1,?RandomToolkit.generateString(12)); ????????????pstmt.setString(2,?RandomToolkit.generateString(24)); ????????????pstmt.setDate(3,?new?Date(System.currentTimeMillis())); ????????????pstmt.setDate(4,?new?Date(System.currentTimeMillis())); ????????????//加入批处理 ????????????pstmt.addBatch(); ????} ????pstmt.executeBatch();????//执行批处理 ????pstmt.close(); ????myBroker.freeConnection(conn);?//连接归池 }
使用多值插入SQL,SQL语句的总长度减少,即减少了网络IO,同时也降低了连接次数,数据库一次SQL解析,能够插入多条数据。
在一个事务中提交大量INSERT语句可以提高性能。
1、将表的存储引擎修改为myisam2、将 sql 拼接成字符串,每 1000 条左右提交事务。
///? ????????///?执行多条SQL语句,实现数据库事务。 ????????///?mysql数据库 ????????///?多条SQL语句 ????????public?void?ExecuteSqlTran(List?SQLStringList) ????????{ ????????????using?(MySqlConnection?conn?=?new?MySqlConnection(connectionString)) ????????????{ ????????????????if?(DBVariable.flag) ????????????????{ ????????????????????conn.Open(); ????????????????????MySqlCommand?cmd?=?new?MySqlCommand(); ????????????????????cmd.Connection?=?conn; ????????????????????MySqlTransaction?tx?=?conn.BeginTransaction(); ????????????????????cmd.Transaction?=?tx; ????????????????????try ????????????????????{ ????????????????????????for?(int?n?=?0;?n?<?SQLStringList.Count;?n++) ????????????????????????{ ????????????????????????????string?strsql?=?SQLStringList[n].ToString(); ????????????????????????????if?(strsql.Trim().Length?>?1) ????????????????????????????{ ????????????????????????????????cmd.CommandText?=?strsql; ????????????????????????????????cmd.ExecuteNonQuery(); ????????????????????????????} ????????????????????????????//后来加上的 ????????????????????????????if?(n?>?0?&&?(n?%?1000?==?0?||?n?==?SQLStringList.Count?-?1)) ????????????????????????????{ ????????????????????????????????tx.Commit(); ????????????????????????????????tx?=?conn.BeginTransaction(); ????????????????????????????} ????????????????????????} ????????????????????????//tx.Commit();//原来一次性提交 ????????????????????} ????????????????????catch?(System.Data.SqlClient.SqlException?E) ????????????????????{ ????????????????????????tx.Rollback(); ????????????????????????throw?new?Exception(E.Message); ????????????????????} ????????????????} ????????????} ????????}
10w条数据大概用时10s!
欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢:

已在知识星球更新源码解析如下:
最近更新《芋道 SpringBoot 2.X 入门》系列,已经 20 余篇,覆盖了MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。
提供近 3W 行代码的 SpringBoot 示例,以及超 4W 行代码的电商微服务项目。
(编辑:威海站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|