jdbc 执行批量 update 的效率问题

2023-11-27 08:38:53 +08:00
 qee

最近客户要对数据库存储的数据做国密改造,提供了相关的加密 sdk ,原来的数据库表存储的数据要升级成密文。 现在就想用原生的 jdbc 读出数据原文加密后存再进去,但是执行 batchexecute()的方法一次 1000 条,发现巨慢,按我查到都是推荐批量更新,但我这个就是巨慢。然后搞了测试表,结构里的索引什么的都删了还是慢。 数据库情况:postgre ,单表有 100+W 的数据,加密更新四五个字段 代码大致:

    connection.setAutoCommit(false);
    PreparedStatement preparedStatement = connection.prepareStatement("update users set name = ? where id = ?");

	for(int =i;i<res.length;i<1000){
    	preparedStatement.setString(1, "John");
    	preparedStatement.setInt(2, 1);
    	preparedStatement.batchadd()
    }
    

    preparedStatement.executeBatch();
    connection.commit();
    

这个哪位有好的优化思路吗,或者别的方案

2828 次点击
所在节点    数据库
29 条回复
codingbody
2023-11-27 12:32:16 +08:00
@litchinn 有的
litchinn
2023-11-27 12:41:02 +08:00
@codingbody 那我还真不知道,我只见过 reWriteBatchedInserts
qee
2023-11-27 13:58:46 +08:00
@cubecube 主键 id 我留了,测试表其他的索引我为了排除影响都干掉了
qee
2023-11-27 13:59:19 +08:00
@akira 加密很快,问题在于数据库的 update 操作
qee
2023-11-27 14:01:13 +08:00
@xiwh connection.setAutoCommit(false);然后再 commit ,这是个整体提交的事务,但是我看到最终连接后,执行再数据库的连接慢,至于数据库里面怎么执行慢的不确定了
qee
2023-11-27 14:26:15 +08:00
@ZhanXinjia 上面就是用的原始 jdbc ;如果用这个 update 拼接的写法,单个 SQL 很长,我有点担心 sql 能否执行下去;我先得把单线程的效率干上去,才能去考虑多线程。
ZhanXinjia
2023-11-27 14:29:26 +08:00
@qee 我的实践是一次刷 1000 条,这个 size 效果比较好。四个线程一起刷。
souryou
2023-11-27 15:05:31 +08:00
我记得 pg 事务更新底层是全量拷贝,而且在处理 mvcc 就更慢了。建议按照 1 楼老哥的方法,不过可以试试边查边改
qee
2023-11-30 11:16:41 +08:00
事实证明,1.rewriteBatchedStatements 参数作为 url 的传参并未生效,pg 的执行方式还是单条导致慢,2.用 2 楼的方式使用单次 update 效率是可以接受的,不过具体的更新条目量得根据实际情况调整; 3. update case when 的写法不推荐,特别是多参数大量更新时可能出现超长的问题。

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

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

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

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

© 2021 V2EX