如何正确的进行大规模SQL语句的批量操作

来源:互联网 发布:java oa人员管理系统 编辑:程序博客网 时间:2024/05/18 02:29

正确使用Statement的批量SQL命令执行方法

1、现象:问题描述

   系统在对定时导入用户数据到系统数据库功能做大规模数据导入测试,导入用户数据量达到1000万以上,出现“out of memory”严重问题,系统宕机。


2、关键过程:根本原因分析

分析系统用户数据导入过程,该过程分两部分执行:

第一步,从外部部件的数据库中读取所有用户数据,将读取到的数据写入到文件中,文件以10M大小进行分割;

第二步,当所有数据写入到文件中后,创建一个PreparedStatement对象(PreparedStatement类继承了

Statement类),根据文件中的每一条记录创建一条insert的SQL命令语句,再调用addBatch(String sql)方法将创建的SQL命令语句添加到刚刚创建的PreparedStatement对象的命令列表中,最后调用executeBatch()方法将命令列表中的所有SQL命令逐一执行。出现“out of memory”的原因恰恰就出在第二步中的调用addBatch(String sql)方法将创建的String型SQL语句添加到PreparedStatement对象的命令列表中,代码中是将所有数据文件中的数据一次性读入,根据每一条数据创建一条SQL语句,全部添加到PreparedStatement对

象的命令列表后,再调用executeBatch()方法,这样,1400万条用户数据就要创建1400万条SQL语句保存在内存中,一条String型的SQL语句至少有164个字节,1400万条就是14000000*164=2296000000字节,也就是说至少需要2.296G内存容量,而安装系统的服务器的内存容量配置只有1G,这样显然要“out of memory”了。


3、结论:解决方案及效果

   根据以上的分析结果,将第二步数据库操作修改为,当PreparedStatement对象命令列表中的SQL语句达到一定数量(该数量由配置文件配置,可以根据服务器的不同配置来设定该值)后,就调用一次executeBatch()方法,执行命令列表中的SQL语句,然后调用clearBatch()方法清空命令列表中的SQL语句,再继续向命令列表中添加SQL语句,如此循环,直到将数据文件中的所有数据全部导入到MCS的数据表。经过以上修改,再次进行1400万用户数据的导入测试,“out of memory”的问题再也没有出现了。


4、经验总结:预防措施和规范建议

   在使用Statement的批量SQL命令操作的时候,一定要注意写入到内存中命令列表的SQL语句的数量级,在小规模的数据量下,可以将所有SQL语句添加到命令列表中,一次性执行executeBatch()方法,但是在大规模数据量的情况下,就应该分批将SQL语句添加到命令列表中,并在每次调用executeBatch()方法后,调用clearBatch()方法将命令列表中的SQL语句清空,注意了,一定要记得调用clearBatch()方法清空命令列表,不然即使分批添加SQL语句,一样要“out of memory”。同时由这个问题,我们也可以引申开来考虑考虑在编写将数据保存在内存中的操作的时候,也应该注意实际系统运行环境的内存配置所能支持的数据量,千万不能不管三七二十一的将数据一股脑儿往内存里塞。

原创粉丝点击