大数据量插入数据库
大数据量插入数据库
大数据量下,提高插入速度的方法。
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;
表优化方面:
参考: