SQL N+1问题

什么是N+1问题?
在两个表存在一对一,一对多,多对一,多对多等关联信息时,查询一条数据会衍生N条查询的情况就是N+1问题。
比如两个实体类A、B。A与B数一对多,B与A是多对一。
在查询A时,会执行的语句如下:
1.从A表查找符合要求的属性,此时符合条件的数据有N条,SQL语句执行了1次。
2.对于每一条符合的数据,通过它的id去B表查关联信息,此时SQL语句执行了N次。
总计查出A和A关联的B数据共执行SQL语句N+1条

如何减少N+1

  1. 通过连接(内,左、右连接)解决
  2. JPA的配置
    spring.jpa.properties.hibernate.default_batch_fetch_size=??为批量执行大小
    原理是将之前每个sql的执行改为通过关键词in来执行。?为in里面的个数
  3. @BatchSize(size=?)注解
    跟JPA配置的原理一致,但@BatchSize的使用具有局限性,不能作用于 @ManyToOne@OneToOne的关联关系上,只能使用在@ManyToMany@OneToMany
  4. 使用@Fetch()注解
    @Fetch(FetchMode.JOIN): 始终立刻加载,使用外连(outer join)查询的同时加载关联对象,忽略FetchType.LAZY设定。
    @Fetch(FetchMode.SELECT) :默认懒加载(除非设定关联属性lazy=false),当访问每一个关联对象时加载该对象,会累计产生N+1条sql语句
    @Fetch(FetchMode.SUBSELECT) 默认懒加载(除非设定关联属性lazy=false),在访问第一个关联对象时加载所有的关联对象。会累计产生两条sql语句。且FetchType设定有效。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值