文档章节

两种极端情况的案例:N+1次查询和笛卡尔积

猪刚烈
 猪刚烈
发布于 2014/10/12 11:39
字数 926
阅读 49
收藏 0

「深度学习福利」大神带你进阶工程师,立即查看>>>

前一篇文章两种极端:频繁的查询和巨大的结果集讲到了Hibernate加载数据时可能会出现的两种极端情况:频繁的查询和一次查出巨大的结果集。其中:N+1次查询是前一种情况的一个典型案例,笛卡尔积则是后一种情况的典型案例。下面分别简单地再总结一下这两种极端案例出现的原因以及调优方法。

 

一.N+1次查询

    如果一个集合是lazy loading的,那么在第一次访问到这个集合时,hibernate会生成一个select被这个集合加载出来。这是N+1中的1。紧接着,在迭代这个集合的过程中,如果要访问集合元素所依赖的其他关联对象时,若它的关联对象也是lazy loading的,那么hibernate会生成一个select从数据库中加载出这个关联对象。这样,N次循环就会生成n个select,这就是N+1中的N.

    解决N+1次查询需要在制定动态抓取策略时eager fetch出集合和集合元素的依赖对象,这样只会生成一条SQL。具体做法是在HOL中,使用fetch关键字来抓取所需要的对象。在Criteria中使用setFetchMode方法设置目标抓取对象。具体示例请参考JPwH-13.5.2

 

 

二.笛卡尔积

    N+1次查询的反面就是笛卡尔积。一般来说,通过定制动态抓取策略,不会加载出我们不需要的数据,但是有一种情况下,即使我们只加载必需对象也会造成大量数据被select出来,这就是抓取“平行”集合导致的笛卡尔积。

    例如:一个Forum有一个Moderator集合,大小为3和一个Thread集合,大小为100。如果在加载Forum时,单独抓取Moderator集合,结果集是3,单独抓取Thread集合,结果集是100,同时抓取这两个集合的结果集是两个集合的加乘(也就是笛卡尔积)为:3*100.如果还有第三个集合,大小是50的话,那结果集就会变成3*100*50. 因此我们可以看到:抓取“平行”集合会产生笛卡尔积,如果集合很多或集合中的元素很多,会使结果集急剧的膨胀。一个巨大的结果集所带来的性能损失是什么呢?想想数据库服务器处理这个条数据所花的时间,占用的服务器的内存,通过网络传输这些数据,以即到了应用服务器占用的内存和hibernate封装这些数据所花费的时间,和这些开销相比,分成两三个SQL(会成数量级的减小结果集)来获取数据要快得多得多。

    HIbernate并不禁止我们产生笛卡尔积,也就是说,你可以在一个抓取计划中抓取多个“平行”集合。但是有一个例外,就是bag集合。Hibernate不允许同时抓取两个以上的bag集合。这是因为:The resultset of a product can’t be converted into bag collections, because Hibernate can’t know which rows contain duplicates that are valid (bags allow duplicates) and which aren’t.

    对于“平行”集合的问题,在抓取时要灵活应对,如果预计到结果集会很大,那么就不要使用join fetch,而要使用subselect fetch!subselect fetch是平行集合的推荐优化方案。

    关于N+1次查询和笛卡尔积,请参考JPwH_13.2.5节。

 

 

 

 

   

 

 

 

猪刚烈

猪刚烈

粉丝 22
博文 708
码字总数 110
作品 1
海淀
程序员
私信 提问
加载中
请先登录后再评论。
访问安全控制解决方案

本文是《轻量级 Java Web 框架架构设计》的系列博文。 今天想和大家简单的分享一下,在 Smart 中是如何做到访问安全控制的。也就是说,当没有登录或 Session 过期时所做的操作,会自动退回到...

黄勇
2013/11/03
3.6K
8
开源数据访问组件--Smark.Data

Smark.Data是基于Ado.net实现的数据访问组件,提供基于强类型的查询表达式进行灵活的数据查询,统计,修改和删除等操作;采用基于条件驱动的操作模式,使数据操作更简单轻松;内部通过标准SQL...

泥水佬
2013/03/12
2.6K
0
超快的css selector引擎--kquery 2.0

kquery是一款基于javascript完整实现css3选择器引擎. 兼容所有主流浏览器ie6+/chrome/firefox/opera/safari, 压缩和gzip之后仅8kb大小。智能编译引擎优化去除不必要的逻辑, 查询速度远胜于...

aaron.xiao
2012/10/23
721
0
CSS 选择器--Q.js

1, 和Sizzle的兼容 Q(expr, context, result, seed) Q.matches 支持Sizzle特别的setFilter伪类如:even,:first,:last,:lt... 支持复杂的:not和:has选择器(和sizzle一样) 2, 结果的正确性 Si...

hackwaly
2012/10/23
4.6K
0
12306.CN 订票助手

这是一个用于辅助在12306.CN上订票的Chrome&Firefox脚本。 这是一个可以运行在遨游3、Chrome、猎豹或Firefox浏览器上的脚本扩展,可以帮助您在 12306.CN 购买火车票(或抢火车票?),反正就...

匿名
2013/01/16
9.6K
0

没有更多内容

加载失败,请刷新页面

加载更多

使用旁路输出(side output)来拆分和复制流

  我们在处理数据的时候,有时候想对不同情况的数据进行不同的处理,那么就需要把流进行拆分或者复制。 如果是使用filter来进行拆分,也能满足我们的需求,但每次筛选都要保留整个流,然后...

osc_ct0tt1cu
53分钟前
18
0
Azure AD 与 AWS IAM 集成实现SSO—上(Azure部分)

整体的架构和流程是下面这个样子: Azure部分: 登录Azure的portal通过Azure Active Directory创建一个测试用户: 返回Azure Active Directory 创建新的应用程序 Amazon Web Service 搜索 Am...

osc_bgs3qxk5
54分钟前
0
0
Azure AD 与 AWS IAM 集成实现SSO—下(AWS部分)

再回顾一下架构,我们都要做什么,别乱: 看来在AWS上做的工作要多一些。 登录AWS控制台: 进入到IAM这个服务: 在配置提供程序中,选择SAML,提供商名称自定义,比如WAAD,将刚才下载的元数...

osc_ibuoui1c
56分钟前
0
0
AWS DevOps 通过Config自动审计Security Group配置——上篇

这个实验的一个场景是,运维同事设计安全组Security Group的时候,打开了除了HTTP和HTTPS的入口访问权限。其他协议或端口如果打开,除了审计不通过的同时,会自动触发一个函数将它修改成我们...

osc_l330x9u1
56分钟前
3
0
AWS DevOps 通过Config自动审计Security Group配置——下篇

再讲一下背景, 这个实验的一个场景是,运维同事设计安全组Security Group的时候,打开了除了HTTP和HTTPS的入口访问权限。其他协议或端口如果打开,除了审计不通过的同时,会自动触发一个函数...

osc_cudh2wh2
58分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部