for 循环中执行 sql 语句,为什么效率低下?

2020-10-28 16:05:49 +08:00
 zw1one

代码错误示例( java ):

for(PO po : poList){
  dao.insert(po);
}

已经用批量提交 /拼接 insert 语句的方式去除了 for 循环,效率也正常了。但是想问下,大家都知道这种操作它效率低,可是它具体低在哪呢?

我大概猜的几个点:

各位大佬,哪里有参考资料之类的可以看看吗 : (

5766 次点击
所在节点    Java
26 条回复
passerbytiny
2020-10-29 09:41:42 +08:00
一、只要是 for 循环中的 sql,不管是插入还是查询,都是可以使用批量的方式替代的。
二、一次扛两桶水,相比每次扛一桶水扛两次,有效付出是一样的,但通常前者的无效付出更少(一种例外情况是,没有那能力还硬扛导致路上水撒了最终变成先扛一桶半再扛一桶)。简单说就是通常情况下批量比循环好。

所以,并不是 for 循环中用 sql 效率底下,而是改成批量模式会更好。
ytymf
2020-10-29 09:46:18 +08:00
楼上说的不错,日志开销也是很大一部分
1194129822
2020-10-29 12:27:54 +08:00
不要以为 JDBC addBatch 和 mybatis BatchExecutor 就是真正的批量提交!!!这个功能要先开启才能用,在 JDBC url 后面加 rewriteBatchedStatements=true,不然还是走的循环插入。
kingofzihua
2020-10-29 14:57:38 +08:00
你下楼买 10 瓶水
方案 1:每次买一瓶,跑 10 次 => for 循环
方案 2:一次买 10 瓶 => 不用 for 循环

所以不用 for 循环进行执行 sql

但是如果你 1 次拿不了,可以 每次取 3 条 for
constructor
2020-10-29 16:30:58 +08:00
插入 10000 条数据实测结果:
一次性批量插入 1 万条: 118.087ms
开启事务循环插入 1 万条: 16.562s
不开启事务循环插入 1 万条: 42.204s

js 代码: https://gist.github.com/xuxucode/e16d9df4476e2e10e3858287c442a778
aragakiyuii
2020-10-29 17:02:10 +08:00
我觉得在忽略数据库本身性能的情况下,无论用什么 orm,只要能保证这些 insert 在一个事务里提交执行就 ok

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/719480

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX