一个小小的批量插入,被面试官追问了6次

面试经常被问到“MyBatis批量入库时,xml的foreach和java的foreach,性能上有什么区别?”。

首先需要明确一点,优先使用批量插入,而不是在Java中通过循环单条插入。

很多小伙伴都知道这个结论,但是,为啥?很少有人能说出个所以然来。

就算我不知道,你也不能反反复复问我“同一个问题”吧?

1、MyBatis批量入库时,xml的foreach和java的foreach,性能上有什么区别?

批量入库时,如果通过Java循环语句一条一条入库,每一条SQL都需要涉及到一次数据库的操作,包括网络IO以及磁盘IO,可想而知,这个效率是非常低下的。

xml中使用foreach的方式会一次性发送给数据库执行,只需要进行一次网络IO,提高了效率。

但是,xml中的foreach可能会导致内存溢出OOM问题,因为它会一次性将所有数据加载到内存中。而java中的foreach可以有效避免这个问题,因为它会分批次处理数据,每次只处理一部分数据,从而减少内存的使用。

如果操作比较复杂,例如需要进行复杂的计算或者转换,那么使用java中的foreach可能会更快,因为它可以直接利用java的强大功能,而不需要通过xml进行转换。

孰重孰轻,就需要面试官自己拿捏了~

​看新机会的

技术大厂,待遇之类的给的还可以,就是偶尔有加班(放心,加班有加班费)

前后端测试捞人,多地有空位,感兴趣的可以试试~​

2、在MyBatis中,对于<foreach>标签的使用,通常有几种常见的优化方法?

比如避免一次性传递过大的数据集合到foreach中,可以通过分批次处理数据或者在业务层先进行数据过滤和筛选。

预编译SQL语句、优化SQL语句,减少foreach编译的工作量。

对于重复执行的SQL语句,可以利用mybatis的缓存机制来减少数据库的访问次数。

对于关联查询,可以考虑使用mybatis的懒加载特性,延迟加载关联数据,减少一次性加载的数据量。

3、MyBatis foreach批量插入会有什么问题?

foreach在处理大量数据时会消耗大量内存。因为foreach需要将所有要插入的数据加载到内存中,如果数据量过大,可能会导致内存溢出。

有些数据库对单条SQL语句中可以插入的数据量有限制。如果超过这个限制,foreach生成的批量插入语句将无法执行。

使用foreach进行批量插入时,需要注意事务的管理。如果部分插入失败,可能需要进行回滚操作。

foreach会使SQL语句变得复杂,可能影响代码的可读性和可维护性。

4、当使用foreach进行批量插入时,如何处理可能出现的事务问题?内存不足怎么办?

本质上这两个是一个问题,就是SQL执行慢,一次性执行SQL数量大的问题。

大多数数据库都提供了事务管理功能,可以确保一组操作要么全部成功,要么全部失败。在执行批量插入操作前,开始一个数据库事务,如果所有插入操作都成功,则提交事务;如果有任何一条插入操作失败,则回滚事务。

如果一次插入大量数据,可以考虑分批插入。这样,即使某一批插入失败,也不会影响到其他批次的插入。

优化foreach生成的SQL语句,避免因SQL语句过长或过于复杂而导致的问题。

比如MySQL的INSERT INTO ... VALUES语法 通常比使用foreach进行批量插入更高效,也更可靠。

5、MyBati foreach批量插入时如何处理死锁问题?

当使用MyBatis的foreach进行批量插入时,可能会遇到死锁问题。这主要是因为多个事务同时尝试获取相同的资源(如数据库的行或表),并且每个事务都在等待其他事务释放资源,从而导致了死锁。

(1)优化SQL语句

确保SQL语句尽可能高效,避免不必要的全表扫描或复杂的联接操作,这可以减少事务持有锁的时间,从而降低死锁的可能性。

不管遇到什么问题,你就回答优化SQL,基本上都没毛病。

(2)设置锁超时

为事务设置一个合理的锁超时时间,这样即使发生死锁,也不会导致系统长时间无响应。

(3)使用乐观锁

乐观锁是一种非阻塞性锁,它假设多个事务在同一时间不会冲突,因此不会像悲观锁那样在每次访问数据时都加锁。乐观锁通常用于读取频繁、写入较少的场景。

(4)分批插入

如果一次插入大量数据,可以考虑分批插入。这样,即使某一批插入失败,也不会影响到其他批次的插入。

(5)调整事务隔离级别

较低的隔离级别(如READ UNCOMMITTED)可能会减少死锁的发生,但可能会导致其他问题,如脏读或不可重复读。

6、mybatis foreach批量插入时如果数据库连接池耗尽,如何处理?

(1)增加最大连接数

数据库连接池耗尽了,增加最大连接数,这个回答,没毛病。

(2)优化SQL语句

减少每个连接的使用时间,从而减少连接池耗尽的可能性。

万变不离其宗,优化SQL,没毛病。

(3)分批插入

避免一次性占用过多的连接,从而减少连接池耗尽的可能性。

(4)调整事务隔离级别

降低事务隔离级别可以减少每个事务持有连接的时间,从而减少连接池耗尽的可能性。但需要注意,较低的事务隔离级别可能会导致其他问题,如脏读或不可重复读。

(5)使用更高效的批量插入方法

比如MySQL的INSERT INTO ... VALUES语法。这些方法通常比使用foreach进行批量插入更高效,也更节省连接资源。

感觉每道题的答案都是一样呢?这就对喽,数据库连接池耗尽,本质问题不就是入库的速度太慢了嘛。

(6)定期检查并关闭空闲时间过长的连接,以释放连接资源。

就前面的几个问题,做一个小总结,你会发现,它们的回答大差不差。

通过现象看本质,批量插入会有什么问题?事务问题?内存不足怎么办?如何处理死锁问题?数据库连接池耗尽,如何处理?

这些问题的本质都是因为SQL执行慢,一次性SQL数据量太大,事务提交太慢导致的。

回答的核心都是:如何降低单次事务时间?

  1. 优化SQL语句
  2. 分批插入
  3. 调整事务隔离级别
  4. 使用更高效的批量插入方法

——转载自作者:哪吒编程

全部评论
mark批量插入优化
点赞 回复 分享
发布于 04-03 14:07 天津

相关推荐

HTTP协议是一种用于在Web浏览器和Web服务器之间通信的协议。它是一个客户端-服务器协议,用于请求和传输超文本标记语言(HTML)文档。HTTP定义了:https://www.nowcoder.com/issue/tutorial?zhuanlanId=Mg58Em&amp;amp;uuid=43521d43a8e341f888324dd690363024客户端如何发送请求服务器如何响应请求工作原理:https://www.nowcoder.com/issue/tutorial?zhuanlanId=Mg58Em&amp;amp;uuid=43521d43a8e341f888324dd690363024#牛客AI配图神器#当用户通过浏览器访问网页时,浏览器会向服务器发送HTTP请求。&nbsp;服务器接收请求并根据请求内容进行处理。&nbsp;服务器处理完成后,将相应的HTML文件或其他文件返回给浏览器,浏览器将文件解析后显示给用户。HTTP工作基于请求-响应模型。&nbsp;客户端发送一个请求给服务器,然后等待服务器的响应。&nbsp;请求和响应都包含了一个Header和一个Body部分。Header部分包含了请求或响应的元数据,如请求类型、URL、协议版本、身份验证信息、缓存控制等。Body部分包含了实际的数据,如HTML文件、图像、视频、音频等。HTTP协议使用TCP/IP协议传输数据。当建立连接时,客户端与服务器之间将建立一条TCP连接,并在连接上发送HTTP请求和响应。连接还可以保持开放状态,以允许多个请求和响应使用同一连接。当不再需要连接时,可以通过关闭TCP连接来终止通信。HTTPS是在HTTP上添加了安全层(SSL&nbsp;/&nbsp;TLS),提供了数据加密和身份验证功能,以保护用户的隐私和安全。
点赞 评论 收藏
分享
04-01 16:13
已编辑
华中科技大学 golang
#后端开发#&nbsp;&nbsp;#暑期实习#&nbsp;&nbsp;#后端开发#&nbsp;&nbsp;#美团#&nbsp;【听说三天没消息自动回人才库,其实已经绝望了,感恩团爹高抬贵手,不面了,当团孝子了】早知道,&nbsp;还是java(bg双九无实习玩具项目&nbsp;&nbsp;golang)一面1.&nbsp;浏览器输入网址到呈现页面过程?&nbsp;&nbsp;1.&nbsp;Dhcp&nbsp;dns&nbsp;http&nbsp;tcp&nbsp;ip&nbsp;arp&nbsp;浏览器渲染【经典起手式】2.&nbsp;你提到tcp协议,讲讲连接过程,具体讲讲序列号确认号关系?&nbsp;&nbsp;1.&nbsp;三次握手&nbsp;&nbsp;2.&nbsp;确认号&nbsp;=&nbsp;收到的对方序列号&nbsp;+&nbsp;1【感觉当时没讲清楚他又追问了一下】3.&nbsp;tcp报文结构,具体讲讲包含哪些字段及作用?&nbsp;&nbsp;1.&nbsp;说了源端口、目的端口、序列号、确认号、窗口大小、状态位、首部大小、紧急指针、选项,漏了校验和【还好面试前刚整理过】4.&nbsp;你提到报文长度,这个有上限吗?&nbsp;&nbsp;1.&nbsp;有的兄弟,有的。mtu&nbsp;mss,具体大小忘了。【我真不记得数啊&nbsp;1500好像】5.&nbsp;传输层除了tcp还有别的吗?&nbsp;&nbsp;1.&nbsp;UDP&nbsp;然后说了说区别:数据包、无连接、不可靠,以及适用场景6.&nbsp;操作系统学过吧,讲讲死锁是什么?如何避免?&nbsp;&nbsp;1.&nbsp;说了说什么循环等待不可剥夺,记不太清楚具体词了,干脆举了个例子说明了一下;&nbsp;&nbsp;2.&nbsp;破坏三个条件【汗流浃背&nbsp;忘了这块了】7.&nbsp;银行家算法有了解过么?具体说下思想?&nbsp;&nbsp;1.&nbsp;了解过,避免死锁的,具体忘了【两年前我肯定记得】8.&nbsp;没关系,那说下cpu中断执行过程?&nbsp;&nbsp;1.&nbsp;硬中断保存上下文,然后软中断;&nbsp;&nbsp;2.&nbsp;软中断去中断向量表查处理程序入口,执行完恢复现场返回;9.&nbsp;刚才提到用户态、内核态,解释一下?&nbsp;&nbsp;1.&nbsp;权限控制机制,用户空间,内核空间讲了讲【这也没背&nbsp;全靠老本&nbsp;感恩攻防实践TnT&nbsp;】10.&nbsp;看你项目用到了数据库,mysql、Redis和mongoDB?&nbsp;&nbsp;1.&nbsp;前两者用的多【mongoDB语法是真难写,千万别问我】11.&nbsp;讲讲mysql和redis区别?&nbsp;&nbsp;1.&nbsp;原理上关系/非关系,结构固定/灵活;&nbsp;&nbsp;2.&nbsp;mysql在磁盘中负责持久化;redis在内存中负责缓存,更快;12.&nbsp;如何定义关系型/非关系型?&nbsp;&nbsp;1.&nbsp;关系型行和列,非关系型更灵活,不固定,如redis是Kv对;【浅薄认知&nbsp;自信说出】13.&nbsp;关系型数据库的相关规范?&nbsp;&nbsp;1.&nbsp;1nf,2nf,3nf,bcnf...【罗列了一下】14.&nbsp;redis为什么快?&nbsp;&nbsp;1.&nbsp;内存中;&nbsp;&nbsp;2.&nbsp;单线程多路复用;&nbsp;&nbsp;3.&nbsp;数据结构优秀,举了sds和跳表例子;15.&nbsp;跳表上层下层节点数1/2的关系是固定的吗?&nbsp;&nbsp;1.&nbsp;不是,添加操作是概率性的,而且这个概率也可以调;16.&nbsp;讲讲查询过程?&nbsp;&nbsp;1.&nbsp;小就向右大就向下17.&nbsp;跳表节点存的是值还是范围?&nbsp;&nbsp;1.&nbsp;值18.&nbsp;redis持久化存储?&nbsp;&nbsp;1.&nbsp;Aof&nbsp;rdb&nbsp;aof+rdb【背诵小林ing】19.&nbsp;aof缺点?&nbsp;&nbsp;1.&nbsp;写入恢复都慢、占内存大20.&nbsp;mongodb是关系型还是?为啥用?&nbsp;&nbsp;1.&nbsp;非关系;&nbsp;&nbsp;2.&nbsp;用mysql存大文档不理想,并且以后想在文章中扩展更多的内容,了解到mongodb比较合适;21.&nbsp;能扩展什么类型?&nbsp;&nbsp;1.&nbsp;啥都可以,流媒体、评论嵌套都支持;22.&nbsp;数据库文章会更新吗?不一致性怎么处理?&nbsp;&nbsp;1.&nbsp;延迟双删23.&nbsp;能彻底避免吗?&nbsp;&nbsp;1.&nbsp;不能吧,可以考虑优化成分布式锁24.&nbsp;延迟双删,第二次删除失败了,怎么处理?&nbsp;&nbsp;1.&nbsp;项目里这个是异步的,因为感觉影响不大所以没考虑处理错误;&nbsp;&nbsp;2.&nbsp;如果要考虑的话,可以引入一个补偿机制,异步删除失败的话可以发一条消息到消息队列,我们收到后去回滚一下msql【即兴发挥&nbsp;知识盲区了感觉】25.&nbsp;你这个回滚是mysql原生支持的,他怎么实现的,自己实现怎么办?&nbsp;&nbsp;1.&nbsp;mvcc,我们也可以仿照mvcc加入版本号字段进行管理;26.&nbsp;kafka使用场景?&nbsp;&nbsp;1.&nbsp;异步&nbsp;削峰&nbsp;解藕&nbsp;日志聚合&nbsp;通信&nbsp;&nbsp;2.&nbsp;项目里主要是用于异步点赞数的更新,避免阻塞正常的阅读过程27.&nbsp;了解kafka之外的消息队列吗?&nbsp;&nbsp;1.&nbsp;不太了解【流汗了】28.&nbsp;为什么选择kafka?&nbsp;&nbsp;1.&nbsp;看博客说适合处理数据量大29.&nbsp;多大?&nbsp;&nbsp;1.&nbsp;百万级【流的汗更多了】30.&nbsp;从底层实现上说说不同消息队列的差异?&nbsp;&nbsp;1.&nbsp;有差异但我不清楚,讲了讲kafka的底层【我真不认识别的&nbsp;呜呜】31.&nbsp;重复消费问题怎么解决?&nbsp;&nbsp;1.&nbsp;幂等生产者,前端限制,加入业务相关的唯一id,加入请求id【想到啥说啥】32.&nbsp;有实习过吗?&nbsp;&nbsp;1.&nbsp;没有,做过一点点开源33.&nbsp;日常学习途径?&nbsp;&nbsp;1.&nbsp;博客、ai、书、前辈【去年双十二的书终于派上用场了,一本本展示】34.&nbsp;用ai干啥?&nbsp;&nbsp;1.&nbsp;科研&nbsp;学习&nbsp;写前端35.&nbsp;写题leetcode143.&nbsp;重排链表36.&nbsp;反问业务:交易结算方面37.&nbsp;反问java怎么学【go选手落泪】---二面1.&nbsp;自我介绍2.&nbsp;意向城市3.&nbsp;转语言吗?&nbsp;&nbsp;1.&nbsp;转,早知道还是java4.&nbsp;实习过吗?&nbsp;&nbsp;1.&nbsp;没有【哭了,每次最痛的问题】5.&nbsp;老师放实习吗?&nbsp;&nbsp;1.&nbsp;放的兄弟,放的6.&nbsp;聊项目7.&nbsp;是合作的吗?小组分工?8.&nbsp;技术选型分歧怎么解决?9.&nbsp;在团队中扮演什么角色?10.&nbsp;讲讲项目难点,怎么解决的?11.&nbsp;长短token讲讲,为啥更安全?12.&nbsp;如何说服合作者重构代码?13.&nbsp;项目里涉及跨库事务一致性如何处理?14.&nbsp;项目里redis适用场景,和mysql一致性怎么保证?15.&nbsp;项目里写了ddd,讲讲&nbsp;&nbsp;1.&nbsp;忘记删了,硬着头皮讲,最后免责声明这东西千人千面,也见不得好16.&nbsp;ddd不足?17.&nbsp;反思你项目架构,哪些可以优化?18.&nbsp;负载均衡用了啥?不同方法的优缺点?19.&nbsp;怎么量化你项目的性能提升?20.&nbsp;你项目的可用性如何进一步提升?21.&nbsp;如何用ai改造你的项目?22.&nbsp;Mysql&nbsp;update执行过程?23.&nbsp;mvcc设计思路有什么好处?24.&nbsp;java了解吗?&nbsp;&nbsp;1.&nbsp;我说只知道语法-&amp;amp;gt;讲讲jvm【我直接汗流浃背了】25.&nbsp;写代码去制造堆的耗尽和溢出&nbsp;&nbsp;1.&nbsp;不断Malloc小空间&nbsp;&nbsp;2.&nbsp;malloc然后越界访问26.&nbsp;url跳转27.&nbsp;一个页面跳转慢,交给你去处理,你会怎么处理这个问题?&nbsp;&nbsp;1.&nbsp;排查确认环节,然后每个环节给出解决措施28.&nbsp;写题【leetcode129&nbsp;求根节点到叶节点数字之和】
nihao111:忍耐王
点赞 评论 收藏
分享
评论
5
22
分享

创作者周榜

更多
牛客网
牛客企业服务