美文网首页程序员
一次数据库insert大量数据的优化记录

一次数据库insert大量数据的优化记录

作者: voxer | 来源:发表于2018-11-04 20:12 被阅读54次

    需求是从一个Oracle数据库迁移数据到阿里云数据库HybridDB for PostgreSQL,这样的工作用kettle比较合适。其中一个表数据是600w条左右,从源数据库插入到目标数据库,就这一个表就需要大概3小时左右

    Kettle应该有优化的空间,我这边先尝试用Java来实现这个表的迁移。
    使用的就是最基础的JDBC连接数据库,需要下载对应的oracle和postgre的jdbc的jar包。
    假定Oracle这张表名我们叫source,目标数据库同样已经创建好同样的表了,我们叫target。

    1. 先从source表查询10w条记录,然后在ResultSet遍历的时候,拼凑一个插入target表的10w条insert语句
      格式大概是:
    insert into target (column1, column2,...) values (v1-1,v1-2,...);
    insert into target (column1, column2,...) values (v2-1,v2-2,...);
    ...
    
    1. 执行 这10w条insert语句。
    2. 循环1,2步骤分60次处理所有数据
      最后测试速度大概插入600w条也需要3个多小时,和kettle持平。

    把方案优化一下,把10w条insert语句改成一条insert语句:

    1. 先从source表查询10w条记录,然后在ResultSet遍历的时候,拼凑一个插入target表的1条insert语句
      格式大概是:
    insert into target (column1, column2,...) values
    (v1-1,v1-2,...),
    (v2-1,v2-2,...),
    ...
    
    1. 执行 这1条insert语句。
    2. 循环1,2步骤分60次处理所有数据
      最后测试速度大概插入600w条只需要20分钟左右,速度提高了很多。

    主要Java代码如下:

    sb.append("insert into interface_item_locator_history (item_id, item_type, org_id, item_org_id, item_class_id, inventory_id, manufactory_id, jyfs, po_tax_rate, so_tax_rate, cost_uc_ti, cost_uc_te, uc_ti, inv_quantity, inv_tc_ti, inv_tc_te, locator_id, inv_date, last_update_date, last_updated_by, creation_date, created_by) values ");
    ResultSet rs = st.executeQuery(sql);
    while (rs.next()) {
        interface_item_locator_history obj = new interface_item_locator_history();
        BigDecimal item_id = rs.getBigDecimal("item_id");
        obj.setItem_id(item_id);
        int item_type = rs.getInt("item_type");
        obj.setItem_type(item_type);
        BigDecimal org_id = rs.getBigDecimal("org_id");
       ... //更多字段
    
        obj.toSQL(sb);//拼凑insert的sql语句
    }
    sb.deleteCharAt(sb.length() - 1);
    st_pg.execute(sb.toString());
    

    代码可以优化和注意的地方是:

    1. StringBuffer构造的时候先设置一个足够大的长度,否则随着lenght的逐渐变大而动态的申请内存会有耗时。

    2. ResultSet对象转成自定义的实体类可以使用反射,否则字段一多,需要写很多代码传递值

    3. 后续还是得尝试优化kettle的速度,用java可以实现,而且灵活,但是需要更多的Java开发工作。

    所有源码可以从Git上下载

    相关文章

      网友评论

        本文标题:一次数据库insert大量数据的优化记录

        本文链接:https://www.haomeiwen.com/subject/ewkdxqtx.html