数据库写性能问题

这两天在测试数据库的性能时发现,更新非常慢,但是如果直接执行sql,不通过jfinal,可以每秒大概4000条,用jfinal大概只有每秒20条,代码如下:

int i;

Clock baseclock = Clock.systemUTC(); 

// get instant of base class and print instant 

Instant instant = baseclock.instant(); 

System.out.println("Instant of Base 1 class "

   + instant); 

for(i=1;i<200;i++) {

new User().set("name","usera").set("school","schoola").save();

}

Instant instant1 = baseclock.instant(); 

System.out.println("Instant of Base 2 class "

   + instant1); 


打印输出如下:

Before invoking /blog/test_call

Instant of Base 1 class 2020-10-03T16:30:10.793Z

Instant of Base 2 class 2020-10-03T16:30:20.401Z

After invoking /blog/test_call

单表增加200条记录,执行了10秒钟。有大神可以给答复一下么?


评论区

JFinal

2020-10-04 10:08

for 循环中一条一条插入的性能肯定是很慢的,用一下 Db.batchSave 方法会快得多

JFinal

2020-10-04 10:10

补充说明一下,jfinal 的数据库操作模块是对 JDBC 的极薄封装,理论上性能就是接近 JDBC, 出现性能问题肯定是必有的问题,例如查询未在索引上,造成全表扫描,再例如, sql 本身就很慢

简单来说,jfinal 只将你的 sql 与 para 直接递送给 JDBC,不干预这个过程

bluewindlan

2020-10-04 10:42

@JFinal 用Db.batchSave 方法是快很多,大概每秒4000次,我有点想不明白的是同样的sql语句,咱们封装的model 直持操作为什么会那么慢,大概只有20条每秒。

糊搞

2020-10-04 10:43

@bluewindlan 没有开事务

bluewindlan

2020-10-04 10:44

@JFinal 另外,我用batchSave方法多次调用的性能也基本是20次每秒,我是不是可以得出这样的结论,咱们封装的通讯频次在20次每秒?

JFinal

2020-10-04 11:04

@bluewindlan 封装的 model 不是慢,而是机制问题

你在 for 循环中 save,每次循环都会连接数据库,解析 sql,传送 sql 拿到结果,这里头除了数据库操作还有 IO 通信的工作

而你用 batch 来 save,整个过程是一次性的,一次性将所有数据发到数据库,这个是有本质区别的

我打个比方,假如一个快递公司要将 4000 个包裹从北京送到上海,如果用 for 循环,那就是每趟送一个包裹,一共需要 4000 趟。 如果每次送 4000 个,则只需一趟

bluewindlan

2020-10-04 11:15

@JFinal 谢谢您的解答,但是这种直接调用model save的使用场景应该也很多吧。有没有办法,保持连接,每次调用,只传送sql,其余建链等等工作是不是可以不用每次都做。

JFinal

2020-10-04 12:10

@bluewindlan 直接 model.save 不是批量场景,就好比账户注册,文章发布这样一次保存一个 model 的场景

热门反馈

扫码入社