mysql/oracle jdbc大数据量插入优化
10.10.6 大数据量插入优化
在很多涉及支付和金融相关的系统中,夜间会进行批处理,在批处理的一开始或最后一般需要将数据回库,因为应用和数据库通常部署在不同的服务器,而且应用所在的服务器一般也不会去安装oracle客户端,同时为了应用管理和开发模式统一,很多会利用mybatis的foreach collection特性,如下:
<insert id="batchInsertStudent" parameterType="List">
insert into /*+ append_values */ t_student(id,name)
<foreach collection="list" item="item" index="index" separator="union all">
select #{item.id}, #{item.name} from dual
</foreach>
</insert>
还有一些开发人员会仿照mysql的写法,拼接成一个巨大的SQL,一次性提交给oracle执行,如下:

这些写法会生成很长的SQL语句,严重浪费客户端内存和oracle服务器共享池,如果这段期间需要生成AWR报告的话,没有这些语句几十秒就完成了,有这些语句的时候可能要十几分钟,生成的AWR文件就有十几兆,并且oracle服务器CPU利用率一直高负载。如果仅仅是如此也就罢了,最主要是这些看似优化的方法实际上性能仅仅比一条条提交提升快了几倍而已,对于一次性加载几十万、几百万行来说,并没有采用真正高效的做法。对于此类需要加载大量数据的方法,如本书第7章所述,应尽可能采用特殊优化的接口而不是为通用CRUD目的实现的接口,比如mybatis提供了批量执行器ExecutorType.BATCH,JDBC也提供了标准的批处理接口。
mybatis批量执行器的实现如下:
<insert id="insertBatch" parameterType="chapter10.batch.pojo.User">
insert into EMP (EMPNO,ENAME,JOB,MGR,SAL,COMM,DEPTNO)
values (#{empno,jdbcType=BIGINT},……,#{deptno,jdbcType=BIGINT})
</insert>
SqlSession session2 = sqlMapper.openSession(ExecutorType.BATCH, false);// 批处理方式 手动提交事务
UserMapper userDao2 = session2.getMapper(UserMapper.class);
try {
long t1 = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
User user_new = new User();
user_new.setComm(i % 10000);
……
user_new.setSal(i % 1000);
userDao2.insertBatch(user_new);
if (i % 10000 == 0) {
session2.commit();
}
}
System.out.println(System.currentTimeMillis() - t1 + "ms");
} finally {
session2.commit();
session2.close();
}
oracle jdbc批处理的实现如下:
Connection connection = dbpool.getConnection();
connection.setAutoCommit(false);
PreparedStatement preparedStatement = connection.prepareStatement("insert into EMP (EMPNO,ENAME,JOB,MGR,SAL,COMM,DEPTNO) values (?,?,?,?,?,?,?)");
long t1 = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
User user_new = new User();
user_new.setComm(i % 10000);
……
preparedStatement.setInt(7, user_new.getDeptno());
preparedStatement.addBatch();
if (i % 10000 == 0) {
preparedStatement.executeBatch();
connection.commit();
}
}
preparedStatement.close();
加载100w数据,使用jdbc Batch需要3秒左右,mybatis batch(标准JDBC批处理)9.2秒,mybatis foreach每5000条(1w时报java.sql.SQLException: ORA-01745: 无效的主机/绑定变量名)提交一次,需要执行203秒左右,甚至不如每行一次、每10000行提交一次的效率,并且子游标的共享内存占用了27M,固定内存加起来占了14M左右,如下:
SQL> select o.sql_id, sharable_mem, persistent_mem, runtime_mem
2 from v$sql o
3 where o.sql_text like '%insert into EMP (%'
4 and sql_text not like '%v$sql%'
5 ;
SQL_ID SHARABLE_MEM PERSISTENT_MEM RUNTIME_MEM
------------- ------------ -------------- -----------
bqwhad7f0gxxd 27473066 9127256 4925984
mysql/oracle jdbc大数据量插入优化的更多相关文章
- C# & SQL Server大数据量插入方式对比
以下内容大部分来自: http://blog.csdn.net/tjvictor/article/details/4360030 部分内容出自互联网,实验结果为亲测. 最近自己开发一个向数据库中插入大 ...
- MySQL分页查询大数据量优化方法
方法1: 直接使用数据库提供的SQL语句 语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N适应场景: 适用于数据量较少的情况(元组百/千级)原因/缺点: ...
- MySQL数据库解决大数据量存储问题
转载自:https://www.cnblogs.com/ryanzheng/p/8334915.html 提问:如何设计或优化千万级别的大表?此外无其他信息,个人觉得这个话题有点范,就只好简单说下该如 ...
- mysql innobackupex xtrabackup 大数据量 备份 还原
大数据量备份与还原,始终是个难点.当MYSQL超10G,用mysqldump来导出就比较慢了.在这里推荐xtrabackup,这个工具比mysqldump要快很多. 一.Xtrabackup介绍 1, ...
- mysql innobackupex xtrabackup 大数据量 备份 还原(转)
原文:http://blog.51yip.com/mysql/1650.html 作者:海底苍鹰 大数据量备份与还原,始终是个难点.当MYSQL超10G,用mysqldump来导出就比较慢了.在这里推 ...
- Mysql千万级大数据量查询优化
来源于:https://blog.csdn.net/A350204530/article/details/79040277 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 ord ...
- sql server 2005 大数据量插入性能对比
sql server 2005大数据量的插入操作 第一,写个存储过程,传入参数,存储过程里面是insert操作, 第二,用System.Data.SqlClient.SqlBulkCopy实例方法, ...
- MYSQL数据库导入大数据量sql文件失败的解决方案
1.在讨论这个问题之前首先介绍一下什么是"大数据量sql文件". 导出sql文件.选择数据库-----右击选择"转储SQL文件"-----选择"结构和 ...
- SQL优化-大数据量分页优化
百万数据量SQL,在进行分页查询时会出现性能问题,例如我们使用PageHelper时,由于分页查询时,PageHelper会拦截查询的语句会进行两个步骤 1.添加 select count(*)fro ...
随机推荐
- Angular1和Aangular4剖析
字面解析: 1.Angular1又名angularJs,从angular2,angular4都不带JS 2.变化:angular2跳转到angular4 架构: 1.angular1是基于MVC 2. ...
- Java Selenium - 几种对话框处理Alert\confirm\prompt
1. Alert , 先用常规办法定位到能触发alert的按钮 , 然后 Alert alert = driver.switchTo().alert(); alert.accept(); 如果aler ...
- 查看手机cpu信息
adb shell getprop ro.product.cpu.abi
- theos第一次编译成功,记录一下
theos 是github 90444af分支上的,下载设置环境变量 vi /etc/profile. 将/opt/theos/bin加入环境变量 运行nic.pl f 输入11生成工程,一路跳过 最 ...
- React对比Vue(02 绑定属性,图片引入,数组循环等对比)
import React, { Component } from 'react'; import girl from '../assets/images/1.jpg' //这个是全局的不要this.s ...
- element-ui的滚动条组件el-scrollbar(官方没有)
<template> <div style="height:600px;"> <el-scrollbar style="height:100 ...
- shiro loginUrl拦截无效
logUrl不拦截 或者 只跳转到/login.jsp 不跳到自己设置登录链接 在springmvc或事务那里 开启spring的显示代理(即cglib),并将shiro的安全管理器交给spring管 ...
- MyBatis基础入门《八》查询参数传入Map
MyBatis基础入门<八>查询参数传入Map 描述: 在执行select查询数据的时候,方法传入的参数是java.util.Map类型. 接口方法: xml文件 注意: 书写SQL语句的 ...
- jQuery-二级导航
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- django admin 处理文本换行空格
使用 linebreaks filter <p>{{ blogpassage.content|linebreaksbr }}<p>