文档章节

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

猪刚烈
 猪刚烈
发布于 2014/10/12 11:39
字数 926
阅读 22
收藏 0
点赞 0
评论 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
海淀
程序员
oracle多表查询之经典面试题

一、笛卡尔积 概念 笛卡尔乘积是指在数学中,两个集合X和Y的笛卡尓积(Cartesian product),又称直积,表示为X × Y,第一个对象是X的成员而第二个对象是Y的所有可能有序对的其中一个成员。...

lkee6760 ⋅ 2017/04/26 ⋅ 0

资金项目性能优化

一、项目背景 该项目是一个对资金还、回款改造的项目。以前的做法是,在签约或者发生标转让的时候生成回款信息,直接插入回款表,下次回款时从回款表里面查找。现在这张表有2亿+条数据,100...

liangxiao ⋅ 2016/05/27 ⋅ 0

【SQL】—多表查询的几种连接方式

前言 最近在项目中用到连接查询,连接查询是关系数据中最主要的查询,包括内连接、外连接等。通过连接运算符可以实现多个表查询。下面来复习一下。 正文 连接查询主要分为三种:内连接、外连...

zt15732625878 ⋅ 01/16 ⋅ 0

杂事杂知识,

以前在写博客中,自己感觉函数,SQL查询常用的没必要多看多学习,今天想处理一个简单笛卡尔积问题,炸了!下面聊聊解决和感觉有意义的知识点 说问题拉点知识关于rownum的,这是Oracle系统查询...

长路慢 ⋅ 02/02 ⋅ 0

oracle使用with as提高查询效率

经常在开发过程中会用到视图或组合查询的情况,但由于涉及表数据经常达到千万级别的笛卡尔积,而且一段查询时会反复调用,但结果输出往往不需要那么多,可以使用with将过滤或处理后的结果先缓...

GeminiLiu ⋅ 2014/01/09 ⋅ 0

mysql多表查询

1、并(union) “并”就是把具有相同字段数目和字段类型的表合并到一起 2、笛卡尔积 笛卡尔积就是没有连接条件表关系的返回的结果 3、内连接(inner join) 针对数据库操作的运算提供了一个专门...

TsingCall ⋅ 2017/10/21 ⋅ 0

关系数据库

关系数据库: 关系模型由:关系数据结构、关系操作集合、关系完整性约束三部分。 关系模型三个方面:完整性约束、关系数据库系统中实现关系操作的一种语言、关系演算。 完整性约束: 关系 域...

mehome ⋅ 2017/04/17 ⋅ 0

生产环境大型sql语句调优实战第一篇(一)

在生产环境中有一条sql语句的性能极差,在早晨非高峰时段运行抽取数据,平均要花费40分钟,有时候竟然要跑10个多小时。 sql语句比较长,需要点耐心往下看。我对表的数据量都做了简单的说明。...

青夜之衫 ⋅ 2017/12/04 ⋅ 0

如何在Sql Server上使用一条SQL查询结果总数并且分页

SELECT * FROM(SELECT [ORDERID],ROW_NUMBER() OVER(ORDER BY ORDERID) RN,COUNT(*) OVER() AS TOTAL FROM [TSQLFUNDAMENTALS2008].[SALES].[ORDERS] ) T WHERE RN BETWEEN 1 AND 20 Total列......

丑矬穷 ⋅ 2014/02/03 ⋅ 0

《数据库系统概念》8-选择、投影等关系运算

关系代数 Relational Algebra中,一元运算符有选择select、投影project、重命名remane,其余的包括并运算union、集合差set diffetence、笛卡尔积cartesian product等为二元运算符。下面学习它...

zhixin9001 ⋅ 2017/11/28 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

SpringCloud 微服务 (六) 服务通信 RestTemplate

壹 通信的方式主要有两种,Http 和 RPC SpringCloud使用的是Http方式通信, Dubbo的通信方式是RPC 记录学习SpringCloud的restful方式: RestTemplate (本篇)、Feign 贰 RestTemplate 类似 Http...

___大侠 ⋅ 14分钟前 ⋅ 0

React创建组件的三种方式

1.无状态函数式组建 无状态函数式组件,也就是你无法使用State,也无法使用组件的生命周期方法,这就决定了函数组件都是展示性组件,接收Props,渲染DOM,而不关注其他逻辑。 无状态函数式组...

kimyeongnam ⋅ 21分钟前 ⋅ 0

react 判断实例类型

今天在写组件的时候想通过判断内部子元素不同而在父元素上应用不同的class,于是首先要解决的就是如何判断子元素的类型。 这里附上一个讲的很全面的文章: https://www.cnblogs.com/onepixel...

球球 ⋅ 28分钟前 ⋅ 0

Centos7备份数据到百度网盘

一、关于 有时候我们需要进行数据备份,如果能自动将数据备份到百度网盘,那将会非常方便。百度网盘有较大的存储空间,而且不怕数据丢失,安全可靠。下面简单的总结一下如何使用 bypy 实现百...

zctzl ⋅ 42分钟前 ⋅ 0

开启远程SSH

SSH默认没有开启账号密码登陆,需要再配置表中修改: vim /etc/ssh/sshd_configPermitRootLogin yes #是否可以使用root账户登陆PasswordAuthentication yes #是都开启密码登陆ser...

Kefy ⋅ 44分钟前 ⋅ 0

Zookeeper3.4.11+Hadoop2.7.6+Hbase2.0.0搭建分布式集群

有段时间没更新博客了,趁着最近有点时间,来完成之前关于集群部署方面的知识。今天主要讲一讲Zookeeper+Hadoop+Hbase分布式集群的搭建,在我前几篇的集群搭建的博客中已经分别讲过了Zookeep...

海岸线的曙光 ⋅ 52分钟前 ⋅ 0

js保留两位小数方法总结

本文是小编针对js保留两位小数这个大家经常遇到的经典问题整理了在各种情况下的函数写法以及遇到问题的分析,以下是全部内容: 一、我们首先从经典的“四舍五入”算法讲起 1、四舍五入的情况...

孟飞阳 ⋅ 今天 ⋅ 0

python log

python log 处理方式 log_demo.py: 日志代码。 #! /usr/bin/env python# -*- coding: utf-8 -*-# __author__ = "Q1mi""""logging配置"""import osimport logging.config# 定义三种......

inidcard ⋅ 今天 ⋅ 0

mysql 中的信息数据库以及 shell 查询 sql

Information_schema 是 MySQL 自带的信息数据库,里面的“表”保存着服务器当前的实时信息。它提供了访问数据库元数据的方式。 什么是元数据呢?元数据是关于数据的数据,如数据库名或表名,...

blackfoxya ⋅ 今天 ⋅ 0

maven配置阿里云镜像享受飞的感觉

1.在maven目录下的conf/setting.xml中找到mirrors添加如下内容,对所有使用改maven打包的项目生效。 <mirror> <id>alimaven</id> <name>aliyun maven</name> <url>http://maven.al......

kalnkaya ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部