Mybatis与JDBC批量插入MySQL数据库性能测试及解决方案

news/2023/6/7 23:10:18

1 背景

系统中需要批量生成单据数据到数据库表,所以采用批量插入数据库的方式。由于系统中ORM操作集成使用的是Mybatis来完成的。

在Mybatis中操作一般使用批量插入的方式如下:

 insert into userinfo (uid, uname, uphone, uaddress)values<foreach collection="list" item="item"index="index" separator=",">(#{item.uid,jdbcType=INTEGER},#{item.uname,jdbcType=VARCHAR},#{item.uphone,jdbcType=VARCHAR},#{item.uaddress,jdbcType=VARCHAR})

在实际生产中发现,这样调用的效率并不高,于是我们迫切地需要寻找一种处理批量插入性能较高的方式——回归原生数据库JDBC操作。我们要分析Mybatis和JDBC的插入性能,来决策适合我们生产系统的批量插入方式。

参考资料中有一篇文章是对Spring Mybatis和Spring JDBC插入效率的测试,由于测试的数据量不多不予置评。

2 Mybatis
2.1 Mybatis测试样本1K
测试10组数据:

时间(ms)

923

412

426

408

405

353

365

344

316

493

2.2 Mybatis测试样本2K
测试10组数据:

时间(ms)

11031

3340

3571

2327

7273

1353

2676

1249

1245

1155

2.3 Mybatis测试样本4K
测试10组数据:

时间(ms)

6070

5565

5731

5400

5830

5543

5469

5697

5528

5399

2.4 Mybatis测试样本6K
测试10组数据:

时间(ms)

13383

12672

13030

13484

13841

12952

13331

13275

13000

13236

2.5 Mybatis测试样本8K
测试10组数据:

时间(ms)

25312

24702

27065

25921

25156

24686

25314

33947

25304

25853

2.6 Mybatis测试样本10K
测试10组数据:

时间(ms)

42148

39209

38548

40109

37820

37728

38178

38481

38157

39032

2.7 Mybatis测试样本15K
测试10组数据:

时间(ms)

98250

88585

87438

89547

88427

89522

83261

80842

87163

84804

2.8 Mybatis测试样本20K
测试10组数据:

时间(ms)

145481

146618

147098

145578

144947

145614

142014

142315

141984

143625

2.9 性能测试样本平均值
2.9.1 测试样本SQL
2.9.1.1 毫秒级SQL【time(ms)】
– DELETE FROMprocess_spend_time_result WHEREpmethod=‘mybatis’;

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=1000 ANDp.pmethod=‘mybatis’;

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=2000 ANDp.pmethod=‘mybatis’;

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=4000 ANDp.pmethod=‘mybatis’;

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=6000 ANDp.pmethod=‘mybatis’;

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=8000 ANDp.pmethod=‘mybatis’;

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=10000 ANDp.pmethod=‘mybatis’;

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=15000 ANDp.pmethod=‘mybatis’;

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=20000 ANDp.pmethod=‘mybatis’;

2.9.1.2 秒级SQL【time(s)】
SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=1000 ANDp.pmethod=‘mybatis’;

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=2000 ANDp.pmethod=‘mybatis’;

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=4000 ANDp.pmethod=‘mybatis’;

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=6000 ANDp.pmethod=‘mybatis’;

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=8000 ANDp.pmethod=‘mybatis’;

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=10000 ANDp.pmethod=‘mybatis’;

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=15000 ANDp.pmethod=‘mybatis’;

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=20000 ANDp.pmethod=‘mybatis’;

2.9.2 测试数据汇总
数据4舍5入保留3位小数

测试样例

AVG(s)

1K

0.445

2K

3.522

4K

5.623

6K

13.221

8K

26.326

10K

38.941

15K

87.784

20K

144.527

2.10 Mybatis批量插入问题
2.10.1 问题一:处理性能低下
处理10000条耗时:34292ms

2.10.2 问题二:批量处理数据量大小受限

Windows下需要修改MySQL的my.ini文件加入如下配置内容:

max_allowed_packet=500M
Linux下是在/my.cnf修改添加如上内容。

也可以直接这样设置:

SET GLOBAL max_allowed_packet=1073741824;
但MySQL重启后就不起作用了。

2.10.3 问题三:线程处理锁表
在通过多线程并发处理的时,很容易导致数据库表锁表,使得后续的操作无法进行。

2.10.4 问题四:导致对象回收GC问题
对象超出GC对象回收阀值,导致程序中断。

3 JDBC
3.1 JDBC测试数据1W
测试10组数据:

普通插入(ms)

普通+事务(ms)

普通批量(ms)

批量+事务(MS)

28489

801

31287

3494

30536

3042

35547

1899

25571

2041

31022

3501

27954

2733

28927

2547

29620

1261

34408

1449

27125

819

29318

923

28993

1079

31099

939

27594

2547

33504

3410

27967

781

31646

3587

33145

1293

37030

1912

3.2 JDBC测试数据5W
测试10组数据:

普通插入(ms)

普通+事务(ms)

普通批量(ms)

批量+事务(MS)

131427

11568

168623

6926

132271

19313

231526

9915

192176

5238

227724

10978

185640

18955

227497

41959

211777

11238

184970

9461

208446

5019

263636

23394

253351

14265

227391

24870

225268

17009

229871

5583

163739

9719

230719

16657

215033

15802

238018

5330

3.3 JDBC测试数据10W
测试10组数据:

普通插入(ms)

普通+事务(ms)

普通批量(ms)

批量+事务(MS)

308773

21389

360510

16432

352773

23487

372343

25545

378805

24034

368416

12507

384189

30119

392974

23742

369975

30651

378634

26180

368659

11902

416932

21321

388453

12644

411571

18138

391155

11287

396363

11678

368055

30987

399078

12212

363375

22576

361478

18544

3.4 JDBC测试数据25W
测试10组数据:

普通插入(ms)

普通+事务(ms)

普通批量(ms)

批量+事务(MS)

942067

51343

990800

70103

1070688

28737

1051132

35536

1002076

38065

1222409

89644

1073114

57050

1312620

82354

960697

51733

1338932

33428

1025890

37666

1273338

76934

1017361

50916

1115627

92790

1077821

78650

1175512

52427

1038000

23290

1247797

91801

1200532

75494

1262051

72087

3.5 JDBC测试数据50W
测试10组数据:

普通插入(ms)

普通+事务(ms)

普通批量(ms)

批量+事务(MS)

1914920

166575

2059826

146472

2111596

62807

1897888

125075

2174029

147265

1891542

166921

1948838

61284

2129791

93167

1909861

167575

1856811

56286

1990816

141381

1980060

148012

1896793

48087

2065937

56832

2130856

174388

2019914

113289

2073636

117462

2045715

102792

1966828

141319

1857867

116854

3.6 JDBC测试样本均值
3.6.1 测试样本SQL
3.6.1.1 毫秒级SQL【time(ms)】

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=10000 andp.pmethod=‘batchInsert’;

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=10000 andp.pmethod=‘batchInsert2’;

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=10000 andp.pmethod=‘batchInsertWithTransaction’;

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=10000 andp.pmethod=‘batchInsertWithTransaction2’;

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=50000 andp.pmethod=‘batchInsert’;

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=50000 andp.pmethod=‘batchInsert2’;

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=50000 andp.pmethod=‘batchInsertWithTransaction’;

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=50000 andp.pmethod=‘batchInsertWithTransaction2’;

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=100000 andp.pmethod=‘batchInsert’;

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=100000 andp.pmethod=‘batchInsert2’;

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=100000 andp.pmethod=‘batchInsertWithTransaction’;

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=100000 andp.pmethod=‘batchInsertWithTransaction2’;

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=250000 andp.pmethod=‘batchInsert’;

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=250000 andp.pmethod=‘batchInsert2’;

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=250000 andp.pmethod=‘batchInsertWithTransaction’;

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=250000 andp.pmethod=‘batchInsertWithTransaction2’;

SELECTAVG(p.ptime) FROM process_spend_time_resultp WHEREp.plimit=500000andp.pmethod=‘batchInsert’;

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=500000 andp.pmethod=‘batchInsert2’;

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=500000 andp.pmethod=‘batchInsertWithTransaction’;

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=500000 andp.pmethod=‘batchInsertWithTransaction2’;

3.6.1.2 秒级SQL【time(s)】
SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=10000 andp.pmethod=‘batchInsert’;

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=10000 andp.pmethod=‘batchInsert2’;

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=10000 andp.pmethod=‘batchInsertWithTransaction’;

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=10000 andp.pmethod=‘batchInsertWithTransaction2’;

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=50000 andp.pmethod=‘batchInsert’;

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=50000 andp.pmethod=‘batchInsert2’;

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=50000 andp.pmethod=‘batchInsertWithTransaction’;

SELECTAVG(p.ptime)/1000 FROM process_spend_time_resultp WHEREp.plimit=50000andp.pmethod=‘batchInsertWithTransaction2’;

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=100000 andp.pmethod=‘batchInsert’;

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=100000 andp.pmethod=‘batchInsert2’;

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=100000 andp.pmethod=‘batchInsertWithTransaction’;

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=100000 andp.pmethod=‘batchInsertWithTransaction2’;

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=250000 andp.pmethod=‘batchInsert’;

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=250000 andp.pmethod=‘batchInsert2’;

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=250000 andp.pmethod=‘batchInsertWithTransaction’;

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=250000 andp.pmethod=‘batchInsertWithTransaction2’;

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=500000 andp.pmethod=‘batchInsert’;

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=500000 andp.pmethod=‘batchInsert2’;

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=500000 andp.pmethod=‘batchInsertWithTransaction’;

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=500000 andp.pmethod=‘batchInsertWithTransaction2’;

3.6.2 测试数据汇总
数据4舍5入保留2位小数

测试样例

1W(s)

5W(s)

10W(s)

25W(s)

50W(s)

普通插入

28.70

191.91

367.42

1040.82

2011.82

普通+事务

1.64

12.81

21.91

49.29

122.81

批量插入

32.38

223.00

385.83

1199.02

1980.54

批量+事务

2.37

15.51

18.63

69.71

112.57

3.7 JDBC测试规律总结
3.7.1 规律一:批量插入尽量使用事务控制
数据4舍5入保留2位小数

测试样例

1W(s)

5W(s)

10W(s)

25W(s)

50W(s)

普通插入

28.70

191.91

367.42

1040.82

2011.82

普通+事务

1.64

12.81

21.91

49.29

122.81

批量插入

32.38

223.00

385.83

1199.02

1980.54

批量+事务

2.37

15.51

18.63

69.71

112.57

3.7.2 规律二:事务批量处理的数据量不要太大
数据4舍5入保留2位小数

测试样例

1W(s)

5W(s)

10W(s)

25W(s)

50W(s)

普通插入

28.70

191.91

367.42

1040.82

2011.82

普通+事务

1.64

12.81

21.91

49.29

122.81

批量插入

32.38

223.00

385.83

1199.02

1980.54

批量+事务

2.37

15.51

18.63

69.71

112.57

3.7.3 规律三:适当地设置MySQL参数可以提高数据库性能
数据4舍5入保留2位小数

测试样例

1W(s)

5W(s)

10W(s)

25W(s)

50W(s)

普通插入

28.70

191.91

367.42

1040.82

2011.82

普通+事务

1.64

12.81

21.91

49.29

122.81

批量插入

32.38

223.00

385.83

1199.02

1980.54

批量+事务

2.37

15.51

18.63

69.71

112.57

3.7.4 规律四:处理数据量和时间不是成倍增长
数据4舍5入保留2位小数

测试样例

1W(s)

5W(s)

10W(s)

25W(s)

50W(s)

普通插入

28.70

191.91

367.42

1040.82

2011.82

普通+事务

1.64

12.81

21.91

49.29

122.81

批量插入

32.38

223.00

385.83

1199.02

1980.54

批量+事务

2.37

15.51

18.63

69.71

112.57

3.7.5 规律五:数据库性能随数据量的不断加大而降低
数据4舍5入保留2位小数

测试样例

1W(s)

5W(s)

10W(s)

25W(s)

50W(s)

普通插入

28.70

191.91

367.42

1040.82

2011.82

普通+事务

1.64

12.81

21.91

49.29

122.81

批量插入

32.38

223.00

385.83

1199.02

1980.54

批量+事务

2.37

15.51

18.63

69.71

112.57

4 结论
经过以上测试得出结论:Mybatis的批量适合处理少了数据的批量处理,而JDBC适合大数据量的批量处理。据此,采用JDBC批量+事务处理大数据量的表插入操作是最合适的。

5 方案
因为要考虑JVM的GC所以数据应该限制一下,但鉴于Mybatis大数据量的批量插入效率不高,所以根据数据大小分段治理。

5.1 小于1W使用:Mybatis批量插入方案
对JVM进行调优,但主要的性能瓶颈在批量插入操作。鉴于mybatis在项目开发方面的优势,数据量很小的情况下还是建议使用Mybatis。

5.2 大于1W小于10W使用:JDBC批量+事务处理
对JVM进行调优(设置Stack和GC等)。一般操作30秒以内是可以容忍的性能耗时。

5.3 10W以上数据使用:数据分批+JDBC批量+事务处理
对JVM进行调优(设置Stack和GC等),通过数据分批处理。对于分批处理需要借鉴前面的测试数据来定义分批量的大小,主要是对操作时间调优。

如果是100W、1000W级别的数据量,分批处理可以很大程度地提升插入效率,具体的分批需要通过实践去分配,数据量太大这里就不做实验了。

6 参考资料
JDBC实现往MySQL数据库插入百万数据:http://www.cnblogs.com/fnz0/p/5713102.html

MySQL Max_allowed_packet: http://stackoverflow.com/questions/8062496/how-to-change-max-allowed-packet-size

Spring Mybatis和Spring JDBC的插入效率比较:http://toplchx.iteye.com/blog/1988254

注:另外一种比较高效的导入方式是生成一个文本文件使用MySQL的JDBC LOAD DATA LOCAL INFILE;参考示例:

MySQL使用JDBC LOAD DATA LOCAL INFILE导入注意事项

MySQL使用LOAD DATA LOCAL INFILE数据3-5秒导入40W数据

Java不写文件,LOAD DATA LOCAL INFILE大批量导入数据到MySQL的实现

7.实战演练
注意:事务处理的数据量不能太多。

7.1 JDBC工具类

package com.wlyd.fmcgwms.util.jdbc;

import java.io.IOException;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.util.Properties;

/**

*JDBC连接工具类

*@package com.wlyd.fmcgwms.util.jdbc.JdbcConnection

*@date 2017年4月17日 下午3:32:15

*@author pengjunlin

*@comment

*@update

*/

public class JdbcConnection {

     privatestatic Connection conn = null; 

private static Properties props = null;

static {

   props = new Properties(); try { props.load(JdbcConnection.class.getResourceAsStream("/jdbc.properties")); } catch (IOException e1) { e1.printStackTrace(); } try { Class.forName(props.getProperty("jdbc.driverClass")); } catch (ClassNotFoundException e) { e.printStackTrace(); } }

public static Connection getConn(){

   try { conn = DriverManager.getConnection(props.getProperty("jdbc.jdbcUrl"),props.getProperty("jdbc.user"),props.getProperty("jdbc.password")); conn.setAutoCommit(false); } catch (SQLException e) { e.printStackTrace(); } return conn; 

}

public void closeConn(){

   try { if (conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace();} 

}

}

7.2 批量事务插入
7.2.1 接口
/**

 * jdbc批量插入** @MethodName: jdbcBatchInsert* @Description:* @param user* @param items* @return* @throws Exception* @throws*/int jdbcBatchInsert(EsUser user,List<WmElectronicSheetItem> items) throws Exception;/*** jdbc批量插入** @MethodName: jdbcPerBatchInsert* @Description:* @param user* @param items* @return* @throws Exception* @throws*/intjdbcPerBatchInsert(EsUser user, List<WmElectronicSheetItem> items)  throws Exception;

7.2.2 实现
@Override

publicint jdbcBatchInsert(EsUser user, List<WmElectronicSheetItem> items) throws Exception {intflag = 0;intperCount = 100, index = 0;inttimes = items.size() / perCount;longstime=System.currentTimeMillis();try {do {// 休眠50msThread.sleep(50);List<WmElectronicSheetItem>listTemp= null;if (items.size() >= perCount) {listTemp = items.subList(0, perCount);// listTemp是分段处理逻辑的参数}else{listTemp = items.subList(0, items.size());// listTemp是分段处理逻辑的参数}// 遍历当前的值是否正确Stringresult= "";for (inti = 0; i < listTemp.size(); i++) {result += listTemp.get(i) + ",";}Log.getLogger(getClass()).info("第" + (index+1)+ "轮:>>" + result);// 事务单元执行个数==尽量在事务里面处理少一点(事务尽量小一点)jdbcPerBatchInsert(user, listTemp);items.removeAll(listTemp);Log.getLogger(getClass()).info("当前剩余集合长度:>>" + items.size());index++;}while(index<= times);// 计算时间longetime=System.currentTimeMillis();Log.getLogger(getClass()).info(">>封装面单号批量事务插入总共耗时-----------------------:"+(etime-stime)+"ms!");}catch(Exception e) {e.printStackTrace();flag=2;Log.getLogger(getClass()).error("JDBC批量执行插入异常:>>" + items.size());thrownew RuntimeException();}returnflag;}@OverridepublicintjdbcPerBatchInsert(EsUser user, List<WmElectronicSheetItem> items)throws Exception {intflag=0;Connectionconn=JdbcConnection.getConn();PreparedStatementpstm= null;try {Stringsql= "insert intowm_electronic_sheet_item_?  ("+"WESI_WESB_ID,WESI_CARRIER_CODE,WESI_START_CHARACTER,WESI_SEQUENCE,"+"WESI_WAREHOUSE_ID, WESI_CODE,WESI_STATE, "+"CREATOR, CREATE_TIME, MODIFIER,MODIFY_TIME) values"+"(?, ?, ?,  ?, ?, ?, ?, ?, ?, ?, ?)";conn.setAutoCommit(false);Log.getLogger(getClass()).info(">>>>>>验证JDBC连接:"+(conn!=null));for (inti = 0, j = items.size(); i < j; i++) {WmElectronicSheetItemitem= items.get(i);pstm = conn.prepareStatement(sql);pstm.setInt(1, Integer.valueOf(user.getEsCorCode())); // tableNamepstm.setInt(2, item.getWesiWesbId());// WESI_WESB_IDpstm.setString(3, item.getWesiCarrierCode());// WESI_CARRIER_CODEpstm.setString(4, item.getWesiStartCharacter());// WESI_START_CHARACTERpstm.setString(5, item.getWesiSequence());// WESI_SEQUENCEpstm.setInt(6, item.getWesiWarehouseId());// WESI_WAREHOUSE_IDpstm.setString(7, item.getWesiCode());// WESI_CODEpstm.setInt(8, item.getWesiState());// WESI_STATEpstm.setInt(9, user.getEsId());// CREATORpstm.setTimestamp(10,new java.sql.Timestamp(new Date().getTime()));// CREATE_TIMEpstm.setInt(11, -1);// MODIFIERpstm.setTimestamp(12, null);// MODIFY_TIMEpstm.executeUpdate();}conn.commit();// 手动提交事务}catch(Exception e) {e.printStackTrace();flag=2;Log.getLogger(getClass()).error("JDBC批量分配事务单元执行插入异常:>>" + items.size());thrownew RuntimeException();}finally{if (pstm != null) {try {pstm.close();}catch(SQLException e) {e.printStackTrace();}}if (conn != null) {conn.close();}}returnflag;}

7.3测试一组数据
测试50000条数据耗时统计:

数据样本事务大小 (每个事务处理的数量)

     耗时(ms)                                             

100

100258

500

75041

1000

68850

3000

78354

通过这种方式提交比较安全不会出现线程锁表问题,事务处理尽量少,根据每次事务提交执行的量可以实现时间上的优化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.exyb.cn/news/show-4558197.html

如若内容造成侵权/违法违规/事实不符,请联系郑州代理记账网进行投诉反馈,一经查实,立即删除!

相关文章

【机器学习笔记】可解释机器学习-学习笔记 Interpretable Machine Learning (Deep Learning)

【机器学习笔记】可解释机器学习-学习笔记 Interpretable Machine Learning (Deep Learning) 目录【机器学习笔记】可解释机器学习-学习笔记 Interpretable Machine Learning (Deep Learning)课前准备Reference (CV Basics)0.1 CV基础Visualize Convolutional Neural Networks …

学习笔记:斯坦福2017季CS231n深度视觉识别课程视频(by Fei-Fei Li, Justin Johnson, Serena Yeung)最优化笔记

最优化&#xff08;上&#xff09; 简介 对于图像数据xi&#xff0c;如果基于参数集W做出的分类预测与真实情况比较一致&#xff0c;那么计算出来的损失值L就很低。现在介绍第三个&#xff0c;也是最后一个关键部分&#xff1a;最优化Optimization。最优化是寻找能使得损失函…

The Google File System论文拜读

The Google File System Sanjay Ghemawat, Howard Gobioff, and Shun-Tak Leung Google∗摘要我们设计并实现了谷歌文件系统&#xff0c;这是一个为大型分布式数据密集型的应用而设计的可伸缩的分布式文件系统。它能够运行在廉价的商用机器上同时又提供了容错率&#xff0c;并且…

STM32CubeMX学习笔记(13)——PWM输出(呼吸灯)使用

一、PWM简介 脉冲宽度调制&#xff08;PWM&#xff09;&#xff0c;是英文“Pulse Width Modulation”的缩写&#xff0c;简称脉宽调试。 是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。广泛应用在从测量、通信到功率控制与变换的许多领域中。 例如上图…

广告投放的那些骚操作

作者&#xff1a;梁丽丽(Lily Leung)&#xff0c;中国第一批程序化广告从业者&#xff0c;《程序化广告》作者&#xff0c;并著有网络白皮书《程序化广告生态实用手册》及《品牌程序化广告投放指南》&#xff0c;暨南大学新闻与传播学院客座教授&#xff0c;公众号&#xff1a;…

GFS的分布式哲学:HDFS的一致性成就,归功于我的失败……

作者介绍陈东明&#xff0c;具有丰富的大规模系统构建和基础架构的研发经验&#xff0c;善于复杂业务需求下的大并发、分布式系统设计和持续优化。近年专注于分布式系统一致性的研究&#xff0c;常年坚持技术文章创作和社区分享。曾就职于饿了么、百度&#xff0c;主导开发饿了…

Leecode 初级算法(1)--从排序数组中删除重复项

leecode 初级算法-从排序数组中删除重复项 从排序数组中删除重复项&#xff08;数组&#xff09; 给定一个排序数组&#xff0c;你需要在原地删除重复出现的元素&#xff0c;使得每个元素只出现一次&#xff0c;返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;…

jenkins停止僵尸作业Click here to forcibly terminate running steps

现象 job执行完成后没有退出&#xff0c;而且不能停止 解决 Jenkins.instance.getItemByFullName("job名").getBuildByNumber(构建号).finish(hudson.model.Result.ABORTED,new java.io.IOException("Aborting build"));