Oracle 批量上传或更新操作(速度可观)

Posted offerNotFound

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle 批量上传或更新操作(速度可观)相关的知识,希望对你有一定的参考价值。

Oracle 批量上传或更新操作(这个版本适用于数据量很小的情况下,上万的数据量已经有点慢了)

别把 BEGINEND 漏掉了,批量的话得用

    <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 批量上传或更新操作(速度可观)的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 批量上传或更新操作(百万数据量也挺快7秒左右)

oracle批量新增更新数据

如何在oracle数据库中的表里批量插入记录

PHP怎样批量更新数据表中某字段的值?

如何批量删除数据库里某个表里的多条记录

MyBatis批量新增和更新