一、问题描述
项目中导入数据时,一次性导入上万条数据,再加上逻辑中对数据的各种校验造成的耗时,所以很容易造成数据库死锁或服务响应超时。之前的插入 sql 语句如下:
insert into test_table(test1, test2, test3, ...) values(#{item.test1}, #{item.test2}, #{item.test3}, ...)
使用这种方式为什么会造成服务超时的情况,可以参考
https://blog.csdn.net/huanghanqian/article/details/83177178,这篇文章,解释的非常好。
二、解决方案
上述文章中,也提出了解决方案,但是由于是项目制,修改 ExecutorType 的话可能会影响其他的地方,所以我的解决方案如下,将数据分批次的插入,代码如下
// insertDataList : 要插入的原始数据 public void batchInsertMethod(List
经测试,15000条数据,时间大概在 10-20s 内。另外,1000 条数据插入一次和 500 条数据插入一次,耗时几乎没有差别,可自行测试。
三、注意
数据库表中存储这么多条数据,肯定是要用到索引的,当数据插入到临时表后,往正式表同步时,我使用的是下面这种方式
insert into test_table1(test1, test2, test3, ...) select a.test1, b.test2, c.test3 from test_a a left join test_b on ... left join test_c on ... where ...
结果发现还是响应超时,那么只好把 sql 语句拿出来 explain 一下,结果发现没有走索引,造成 select 很慢,但是表结构中明明是存在索引的,经排查,问题原因在于连接表的字符集不一样,修改后,变为正常。
修改表结构的字符集 sql 如下:
alter table test_a convert to character set utf8mb4 collate utf8mb4_general_ci;
表结构添加多列唯一索引 sql 如下:
create unique index idx_name on test_a (column1, column2, ...);
四、参考链接
1.https://blog.csdn.net/huanghanqian/article/details/83177178



