使用ORM框架所产生的查询所产生的N+1问题

N+1问题的产生的原因:

     在使用Hiberate、Mybatis等ORM框架时,假设一个User有多个Card,当我们查询所有User的信息时,使用“Select * from User”这一条语句,如果有n个用户会导致n条关联查询Card的sql语句“select * from Card where user_id = ?”(也就是依次将每一个用户的card信息抓取出来),这就是N+1问题,也可以说是1+N问题吧。而这在我们不需要知道User的Card信息,而只是希望知道User的基本信息时,无疑这多余的关联查询是一种性能消耗。就算我们需要知道User的所有Card信息,但当数据量过大时,ORM的这种N+1方式的遍历查询方式也不可取,因为一条外连接sql便可以达到目的,该语句为“select * from User left outer join Card on User .ID=Card.User_ID”。

N+1问题的解决办法:

    基于以上原因,解决办法由二:

    1,在Hibernate或Mybatis等ORM框架时,使用延迟加载(或懒加载)来屏蔽掉关联的N次查询,但只有当我们不需要关联信息的时候可取

    2,使用外连接来达到关联获取信息的目的,Mybatis中使用groupBy(貌似)

 

思考:

    既然N+1会产生相应的性能悲剧,为什么一直还存在ORM框架中,因为我们可以看到,只有在查询所有User,也就是获取一个列表时,关联的N次查询才比较悲剧,如果我们知道User_id,只定位查询一个User,那关联查询语句最多只有两条(在User对应Card的模型中),这是比较有用的方式的。

 

参考资料:http://www.javathinker.org/main.jsp?bc=showessay.jsp&filename=hibernate/hibernate_essay_8.htm

http://cuishen.javaeye.com/blog/544207

http://xiaoye4188.javaeye.com/blog/871050

http://min4450.javaeye.com/blog/286003

你可能感兴趣的:(Hibernate,mybatis,职场,解决,n+1,原因,休闲)