大批量数据库操作

  • Post author:
  • Post category:其他



通过Http接口同步大量数据的思考

1.请求方使用线程池 多线程请求

2.请求方 使用httpclient 一定要用 http线程池(减少建立tcp连接时的性能消耗)

3.处理方不变的数据放入redis缓存中

4.处理方的查询时的sql优化(整理出慢sql进行优化)

5.处理方集群部署。提高处理效率

一、使用myabtis操作数据库


Mybatis之批量更新数据(批量update)_mybatis 批量更新_凡人歌者徐的博客-CSDN博客

当使用mybatis时用foreach的

case when

方式,使用foreach动态标签拼接SQL语句,但是这种方案是最终拼接成一条SQL,而不是多条SQL的长串。减少数据库交互。

update `t_student`
<trim prefix="set" suffixOverrides=",">
    <trim prefix=" `name` = case " suffix=" end, ">
        <foreach collection="list" item="item">
            <if test="item.name != null">
                when `id` = #{item.id} then #{item.name}
            </if>
        </foreach>
    </trim>
    <trim prefix=" `age` = case " suffix=" end, ">
        <foreach collection="list" item="item">
            <if test="item.age != null">
                when `id` = #{item.id} then #{item.age}
            </if>
        </foreach>
    </trim>
</trim>
where
    `id` in
<foreach collection="list" item="item" open="(" close=")" separator=",">
    #{item.id}
</foreach>

二、不用mybatis

使用jdbc或直接使用sql想批量操作数据库时


1、对于大批量数据库操作,使用手动事务提交可以很多程度上提高操作效率,多线程对数据库进行操作时,并非线程数越多操作时间越快,按上述示例大约在2-5个线程时操作时间最快。

 @Autowired
private DataSourceTransactionManager dataSourceTransactionManager;
 
@Autowired
private TransactionDefinition transactionDefinition;
 
/**
 * 由于希望更新操作 一次性完成,需要手动控制添加事务
 * 耗时:24s
 * 从测试结果可以看出,添加事务后插入数据的效率有明显的提升
 */
@Test
void updateStudentWithTrans() {
    List<Student> allStudents = studentMapper.getAll();
    TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
    try {
        allStudents.forEach(s -> {
            //更新教师信息
            String teacher = s.getTeacher();
            String newTeacher = "TNO_" + new Random().nextInt(100);
            s.setTeacher(newTeacher);
            studentMapper.update(s);
        });
        dataSourceTransactionManager.commit(transactionStatus);
    } catch (Throwable e) {
        dataSourceTransactionManager.rollback(transactionStatus);
        throw e;
    }
}


利用多线程事务控制实现大批量数据库操作_多线程操作数据库_十一技术斩的博客-CSDN博客



2、使用sql的原理去优化批量操作(重要)


如何批量更新合并AnalyticDBPostgreSQL数据和背后的方法原理_云原生数据仓库 AnalyticDB PostgreSQL版-阿里云帮助中心


数据库批量插入与更新_数据库批量更新_怪蜀黍客栈的博客-CSDN博客


引言

最近在做项目的时候总是会遇到需要批量插入数据和批量更新数据的时候,故将数据库批量插入与更新的几种方法结合案例总结下。



批量插入


方法一:insert select

有一次在项目中遇到了需要将一张表中的部分字段中的数据存入另一个表中,一开始不知道怎么做,以为是把所有的数据取出来,然后一条条存进去,后来觉得时间效率太慢了,看了看文档发现了有insert select 方法,可以插入某个表中的数据。

—语法

insert into

表名(列名1,列名2)

select 列名1,列名2

from 表名


方法二:insert values 字符串拼接

在后端中常常会有插入大量数据的情况,在这种情况下循环遍历insert values一条一条SQL语句进行执行效率会大大下降。例如执行一条insert values的时间为60ms,那么1000条数据就需要60s的时间,执行时间会随着数据的条数不断增长。所以我们就想要是只执行一次SQL语句那就好了,那么就可以采用字符串拼接的方式进行大批量数据插入。

—语法

insert into

表名(列名1,列名2)

values

(值1,值2),

(值1,值2),

(值1,值2),

(值1,值2)



批量更新


方法一:update when case


在网上看到最多的批量更新语法就是利用when case进行字符串拼接,这个方法在数据量不大的情况下效率很高,但是当数据量太大的时候就会导致SQL语句太长,导致SQL语句执行效率大大下降。

—语法

update 表名 set

列名1 =

case id

when id值1 then 值1

when id值2 then 值2

end,

列名2 =

case id

when id值1 then 值1

when id值2 then 值2

end

where

id in (id值1,id值2);


方法二:update select

有时候在业务中有需要将某张表中的数据,如果一条条取出来再进行update那会使得效率大大下降,数据库也提供了一个很方便的语句,就是使用update select 可以快速更新id值相同的值。

—语法

update 表1

set

表1.列1 = 表2.列1,

表1.列2 = 表2.列2,

表1.列3 = 表2.列3

from (select 列1,列2,列3) as 表2

where

表1.id = 表2.id


方法三:临时表

有时候采用update case的方法会导致SQL语句太长,那么如果你拥有创建临时表的权限,你可以先创建一张临时表,然后将需要更新的数据插入进去,再利用update select的方法将数据大批量更新。

—创建临时表

create table *tmp(

id varchar(36),

name varchar(128)

)

—插入数据

insert into *tmp(id,name)

values

(值1,值2),

(值1,值2)

—更新数据

update 表1

set name = 表2.name

from (select id,name from *tmp) as 表2

where

表1.id = 表2.id

—删除临时表

drop table *tmp



版权声明:本文为weixin_45433031原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。