大数据量插入数据库

大数据量下,提高插入速度的方法。

1、Java代码方面,使用多线程插入,并且使用批处理提交。

2、数据库方面,表结构建立时不要使用索引,要不然插入过程过还要维护索引B+树;修改存储引擎,一般默认是InnoDB.
3、合并数据+事务的方法在较小数据量时,性能提高是很明显的,数据量较大时(1千万以上),性能会急剧下降,这是由于此时数据量超过了innodb_buffer的容量,每次定位索引涉及较多的磁盘读写操作,性能下降较快。而使用合并数据+事务+有序数据的方式在数据量达到千万级以上表现依旧是良好,在数据量较大时,有序数据索引定位较为方便,不需要频繁对磁盘进行读写操作,所以可以维持较高的性能。
注意事项:
1、SQL语句是有长度限制,在进行数据合并在同一SQL中务必不能超过SQL长度限制,通过max_allowed_packet配置可以修改,默认是1M,测试时修改为8M。
2、事务需要控制大小,事务太大可能会影响执行的效率。MySQL有innodb_log_buffer_size配置项,超过这个值会把innodb的数据刷到磁盘中,这时,效率会有所下降。所以比较好的做法是,在数据达到这个这个值前进行事务提交。

###下面方法适用于大量(百万级别的List数据),插入到Oracle表中

private static final int OPENID_PHONE_NUM = 800; //经实践,800一批插入相对较快,这个可以随便定义

private void insertPMeSendToPhoneInfo(List phoneList){

int listSize=phoneList.size();
int toIndex=OPENID_PHONE_NUM;
for(int i = 0;i<phoneList.size();i+=OPENID_PHONE_NUM){
    if(i+OPENID_PHONE_NUM>listSize){//作用为toIndex最后没有800条数据则剩余几条newList中就装几条
        toIndex=listSize-i;
    }
    List<PMeSendToPhone> newPMeSendToPhoneInfo = phoneList.subList(i,i+toIndex);
    //批量插入
    pMeSendToPhoneMapper.batchInsertPMePhoneData(newPMeSendToPhoneInfo);
}

}

/** 接口方法定义
*批量插入

  • @param newPMeSendToPhoneInfo
  • @return
    */
    int batchInsertPMePhoneData(@Param(value = “list”) List newPMeSendToPhoneInfo);
    mybits配置文件定义方法
begin insert into P_ME_SEND_TO_PHONE (PHONEID, PHONE, OPENID, EXTEND_1,EXTEND_2, EXTEND_3) values( SEQ_P_ME_SEND_TO_PHONE.nextval, #{item.phone,jdbcType=VARCHAR}, #{item.openid,jdbcType=VARCHAR}, #{item.extend1,jdbcType=VARCHAR}, #{item.extend2,jdbcType=VARCHAR}, #{item.extend3,jdbcType=VARCHAR} ); end;

表优化方面:
如何优化MySQL千万级表

参考:
MySQL批量千万级数据SQL插入性能优化<细读>
MySql 快速插入千万级大数据的方法示例
大量List数据批量插入数据库很高效的方法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章