Oracle 批量上传或更新操作(速度可观)
Posted offerNotFound
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle 批量上传或更新操作(速度可观)相关的知识,希望对你有一定的参考价值。
Oracle 批量上传或更新操作(这个版本适用于数据量很小的情况下,上万的数据量已经有点慢了)
别把 BEGIN 与 END 漏掉了,批量的话得用
<insert id="对应 Mapper 层方法名" parameterType="java.util.List" >
BEGIN
<foreach collection='list' item='item' separator=';'> MERGE INTO 表名 T USING
(SELECT
SYS_GUID() AS UUID,
#item.xxx,jdbcType=VARCHAR AS xxx,
#item.xxx,jdbcType=VARCHAR AS xxx,
#item.xxx,jdbcType=VARCHAR AS xxx,
...
FROM DUAL ) T1 (T1 为虚拟表,即你要上传的数据)
ON
(T1.xxx = T.xxx AND T1.xxx= T.xxx AND ...)
WHEN MATCHED THEN (满足 ON 的条件就更新)
UPDATE SET T.xxx= T1.xxx,T.xxx= T1.xxx,...
WHEN NOT MATCHED THEN (不满足就插入)
INSERT
(要插入的字段)
VALUES
(T1.UUID,T1.xxx,...)
</foreach>;
END;
</insert>
推荐方案:既然要数据存在就更新,不存在就插入的话,那就直接先插入再删除重复数据吧(百万数据量也挺快,15秒左右,理由:Update 十分消耗资源,能不用就不用)
插入的话 Mybatis-Plus 提供了saveBatch
方法,挺快的。
删除重复数据(方式一):
<delete id="对应 Mapper 层方法名">
delete from 表名 a
where (a.aaa,a.bbb,a.ccc) in
(
select aaa,bbb,ccc
from 表名
group by aaa,bbb,ccc having count(*) > 1)
and rowid not in (select max(rowid) from 表名 group by aaa,bbb,ccc having count(*)>1
)
</delete>
删除重复数据(方式二,只给了思路,代码自行百度):
上面的方式一是直接在原表操作,数据量到千万级别效率就不太理想。因此可以用建立临时表的方法,临时表装的是原表里无重复的数据,然后清空原表,将临时表里的数据装入原表中,最后删除临时表。
既然用到批量,那就少不了线程池了,只能说巨快!
当然也有个为你还没解决,就是它一瞬间就结束了,但其实这时候数据还在加载,就导致还得去再刷新一次数据库才有数据,望哪位大佬知道告知下!
long start = System.currentTimeMillis();
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
8,
Runtime.getRuntime().availableProcessors()+1,
3,
TimeUnit.SECONDS,
new LinkedBlockingDeque<>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
try
for (int i = 0; i < 16; i++)
threadPool.execute(()->
service.saveBatch(fileData, 5000);
);
catch (Exception e)
e.printStackTrace();
finally
threadPool.shutdown();
mapper.deleteOld();
long end = System.currentTimeMillis();
System.out.println("上传耗时:" + (end - start));
以上是关于Oracle 批量上传或更新操作(速度可观)的主要内容,如果未能解决你的问题,请参考以下文章