`
wen866595
  • 浏览: 268882 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

mybatis 批量插入插件

阅读更多

 

背景

项目中有个设计不合理的表,总共 8 个字段,有 5 个索引,有几个索引字段还是 32 位的字符串。该表数据量已达 1 亿,最近每天新增 100 万。根据日志看,有次用户上传一个有 200 行记录的 excel,需要往这个表插入 3940 条记录,耗时 72 秒。这么大延迟是没法接受的。

 

要分析数据库方面的问题,首先是找 DBA 分析下表的情况,说跟以往没多大区别,只是跟这个表有关的插入的执行计划很多。因为这个表的批量插入是这样的:

<select id="batchSave" parameterType="java.util.List">
    INSERT INTO TABLE_NAME(ID,NAME) 
<foreach collection="list"item="itm" separator="union all">
    (SELECT #{itm.id}, #{itm.name} FROM DUAL)
</foreach></select>

这是用 MyBatis 对 Oracle 做批量插入的唯一方法。副作用是:假定 List 的最大长度是 N,那么 Oracle 服务器端就可能有 N 个插入的执行计划。这么多执行计划,DBA 也不乐意去分析呀,而且生成的每个执行计划确实都是很简单的。

 

优化

如果放弃 union all 的方式,则每条记录都需要各提交一次到数据库,显然也不好。

为了解决 N 个执行计划的问题,做到真正的批量插入,只能修改 MyBatis 的执行逻辑,因此就有了这个项目:mybatis-batchinsert-plugin

目前可以批量插入,但不支持返回主键等其他的功能,有空再完善。

 

2
1
分享到:
评论
4 楼 wen866595 2015-08-05  
cywhoyi 写道
wen866595 写道
cywhoyi 写道
我觉得是否考虑数据路由,你这样方式治标不治本


不知道你说的“数据路由”是怎样的方案?

我做这个插件主要是希望达到:
1、解决Oracle服务器端对一个表做插入的执行计划过多的问题;
2、避免用 union all 拼接成一条 sql,导致一条sql里的绑定变量过多;
3、兼容 MyBatis 的用法,在书写方式上不用改变。

这个插件对性能提升不会很显著,在我们的开发数据库上测试时,以1000条为1批,插入40w数据,用 union all 的方式平均一条需要 32ms,用插件大概是 27ms。

不好意思现在回复你,我看了github使劲上性能提升不大,我现在私库里面采用的想法是能否把数据切成多份,然后在路由hash过去,但是对于developer是无缝的,当然包括DML和查询


看起来你是想做分表?如果是单单一个独立的表,是容易的,但如果有多个表之间的关联,就复杂很多了,去尝试下也是不错的。而我目前只想保持最小的改动。
3 楼 cywhoyi 2015-08-05  
wen866595 写道
cywhoyi 写道
我觉得是否考虑数据路由,你这样方式治标不治本


不知道你说的“数据路由”是怎样的方案?

我做这个插件主要是希望达到:
1、解决Oracle服务器端对一个表做插入的执行计划过多的问题;
2、避免用 union all 拼接成一条 sql,导致一条sql里的绑定变量过多;
3、兼容 MyBatis 的用法,在书写方式上不用改变。

这个插件对性能提升不会很显著,在我们的开发数据库上测试时,以1000条为1批,插入40w数据,用 union all 的方式平均一条需要 32ms,用插件大概是 27ms。

不好意思现在回复你,我看了github使劲上性能提升不大,我现在私库里面采用的想法是能否把数据切成多份,然后在路由hash过去,但是对于developer是无缝的,当然包括DML和查询
2 楼 wen866595 2015-08-03  
cywhoyi 写道
我觉得是否考虑数据路由,你这样方式治标不治本


不知道你说的“数据路由”是怎样的方案?

我做这个插件主要是希望达到:
1、解决Oracle服务器端对一个表做插入的执行计划过多的问题;
2、避免用 union all 拼接成一条 sql,导致一条sql里的绑定变量过多;
3、兼容 MyBatis 的用法,在书写方式上不用改变。

这个插件对性能提升不会很显著,在我们的开发数据库上测试时,以1000条为1批,插入40w数据,用 union all 的方式平均一条需要 32ms,用插件大概是 27ms。
1 楼 cywhoyi 2015-08-03  
我觉得是否考虑数据路由,你这样方式治标不治本

相关推荐

Global site tag (gtag.js) - Google Analytics