[NHibernate]N+1 Select查询问题分析
目录
写在前面
在前面的文章(延迟加载,立即加载)中都提到了N+1 Select的问题,总觉得理解的很不到位,也请大家原谅,这也是为什么单独将该问题拿出来做分析的原因。nhibernate的默认Lazy加载方式是解决N+1 select问题的一种方案,而我自身的理解是立即加载可以解决,完全的背道而驰了。写出那篇文章后,对这个问题,一直念念不忘,总觉得哪地方不对劲。由于我对问题的理解很不透彻,也同样造成你的误解,真的很抱歉。
文档与系列文章
[NHibernate]持久化类(Persistent Classes)
[NHibernate]集合类(Collections)映射
[NHibernate]缓存(NHibernate.Caches)
[NHibernate]NHibernate.Tool.hbm2net
[NHibernate]Nhibernate如何映射sqlserver中image字段
[NHibernate]条件查询Criteria Query
N+1 Select查询问题分析
使用sql查询数据的时候,如果select太多,势必也会对数据库造成压力,影响性能。比如如果查询n个Customer对象,则一次查询获得所有的customer对象,然后根据customerid查询关联的Order表。(立即加载的情况下)
一个例子
/// <summary>
/// NHibernateUtil方式,立即加载客户信息及关联的数据
/// </summary>
/// <param name="customerID"></param>
/// <returns></returns>
public Customer GetCustomerByImmediatelyLoadNHibernateUtil(Guid customerID)
{
//获得ISession实例
//通过using的方式将session释放,为了保证是立即加载的数据,而不是延迟加载的
//还记得上篇文章中提到的在延迟加载中,在关闭session情况下,再读取数据的时候就会有一个异常信息
//忘记的可以再回到上一篇文章进行查看
using (ISession session = NHibernateHelper.GetSession())
{
Customer customer = session.Get<Customer>(customerID);
//
// 摘要:
// Force initialization of a proxy or persistent collection.
//
NHibernate.NHibernateUtil.Initialize(customer.Orders);
return customer;
}
}
这里使用NHinernateUtil实用类进行强制立即加载方式,测试代码
protected void btnImmediately_Click(object sender, EventArgs e)
{
Business.CustomerBusiness customerBusiness = new Business.CustomerBusiness();
Customer customer = customerBusiness.GetCustomerByImmediatelyLoadNHibernateUtil(new Guid("B0720295-9541-40B3-9994-610066224DB8"));
bool isInitOrder = NHibernate.NHibernateUtil.IsInitialized(customer.Orders);
}
查看生成的sql语句
本来我们是想查询customer,一次查询就够,可是通过监视到的sql,发现多了一次sql查询,也就是查询customer的关联数据表的数据。
而在延迟加载的情况下,则会在需要的时候才会去查询,性能上面更好。(有关延迟加载的内容,请在系列文章中查找,这里不再赘述了)
如果采用延迟加载方式,生成的sql如下(借用延迟加载文章中的图说明)
一对多关系Lazy加载
多对多关系Lazy加载
order和Product多对多关系,此时生成的sql语句
你可以看到此时生成的sql语句是通过left outer join(左外连接)进行关联数据表的,而此时只生成一条sql语句,明显减少了查询数据的次数。
总结
(1)select语句的数目太多,需要频繁的访问数据库,会影响检索性能。此时可采用sql中的左外连接查询,在一条sql语句中将所有数据查询出来,并且减少了select的次数。
(2)在应用逻辑只需要访问Customer对象,而不需要访问Order对象的场合,加载Order对象完全是多余的操作,这些多余的Order对象白白浪费了许多内存空间。
为了解决以上问题,Hibernate提供了其他两种检索策略:延迟检索策略和迫切左外连接检索策略。延迟检索策略能避免多余加载应用程序不需要访问的关联对象,迫切左外连接检索策略则充分利用了SQL的外连接查询功能,能够减少select语句的数
这里就N+1 select问题做一下特别说明,有问题,如果不想办法解决,总觉得有个疙瘩,早解决,早有好心情。通过本篇的分析,你是不是也对n+1的问题豁然开朗?这也怪我了,当时对那一块理解确实有误,再次感到很抱歉。
[NHibernate]N+1 Select查询问题分析的更多相关文章
- 让OData和NHibernate结合进行动态查询
OData是一个非常灵活的RESTful API,如果要做出强大的查询API,那么OData就强烈推荐了.http://www.odata.org/ OData的特点就是可以根据传入参数动态生成Ent ...
- 为什么忘记commit也会造成select查询的性能问题
今天遇到一个很有意思的问题,一个开发人员反馈在测试服务器ORACLE数据库执行的一条简单SQL语句非常缓慢,他写的一个SQL没有返回任何数据,但是耗费了几分钟的时间.让我检查分析一下原因,分析解决过后 ...
- MySQL 慢查询日志分析及可视化结果
MySQL 慢查询日志分析及可视化结果 MySQL 慢查询日志分析 pt-query-digest分析慢查询日志 pt-query-digest --report slow.log 报告最近半个小时的 ...
- SQL查询性能分析之(not in)、(and not)、()、(!=)性能比较
SQL查询性能分析之(not in).(and not).().(!=)性能比较 SQL Server Bruce 3年前 (2013-01-08) 3284浏览 0评论 <:article c ...
- MYSQL的全表扫描,主键索引(聚集索引、第一索引),非主键索引(非聚集索引、第二索引),覆盖索引四种不同查询的分析
文章出处:http://inter12.iteye.com/blog/1430144 MYSQL的全表扫描,主键索引(聚集索引.第一索引),非主键索引(非聚集索引.第二索引),覆盖索引四种不同查询的分 ...
- select查询的性能
为什么忘记commit也会造成select查询的性能问题 今天遇到一个很有意思的问题,一个开发人员反馈在测试服务器ORACLE数据库执行的一条简单SQL语句非常缓慢,他写的一个SQL没有返回任何数据, ...
- Solr4.8.0源码分析(5)之查询流程分析总述
Solr4.8.0源码分析(5)之查询流程分析总述 前面已经写到,solr查询是通过http发送命令,solr servlet接受并进行处理.所以solr的查询流程从SolrDispatchsFilt ...
- RAC某节点v$asm_disk查询hang分析处理
主题:RAC某节点v$asm_disk查询hang分析处理 环境:Oracle 11.2.0.3 RAC 故障描述:RAC环境2个节点,节点1查询v$asm_disk正常返回结果,节点2查询v$asm ...
- MySQL 通用查询日志和慢查询日志分析
MySQL中的日志包括:错误日志.二进制日志.通用查询日志.慢查询日志等等.这里主要介绍下比较常用的两个功能:通用查询日志和慢查询日志. 1)通用查询日志:记录建立的客户端连接和执行的语句.2)慢查询 ...
随机推荐
- debian/ubuntu安装桌面环境
apt-get install xorg apt-get install gnome 然后startx ubuntu 安装Gnome桌面 1.安装全部桌面环境,其实Ubuntu系列桌面实际上有几种桌面 ...
- 深入理解Java的接口和抽象类
深入理解Java的接口和抽象类 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太多不同的地方.很多人在初学的 ...
- java设计模式之组合模式
组合模式 组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性.掌握组合模式的重点是要理解清楚 “部分/整体” 还有 ”单个对象“ 与 & ...
- UVA11021 Tribles[离散概率 DP]
UVA - 11021 Tribles GRAVITATION, n. “The tendency of all bodies to approach one another with a stren ...
- 基于webmagic的爬虫项目经验小结
大概在1个月前,利用webmagic做了一个爬虫项目,下面是该项目的一些个人心得,贴在这里备份: 一.为什么选择webmagic? 说实话,开源的爬虫框架已经很多了,有各种语言(比如:python.j ...
- Linux下安装VMware Tools 的方法
1.按下 CTRL + ALT 组合键,进入主操作系统,点击VMware虚拟机菜单下的安装虚拟机工具子菜单. 菜单:VM->Install VMware tools....(虚拟机->安 ...
- 种子填充算法描述及C++代码实现
项目需要看了种子填充算法,改进了算法主要去除面积小的部分.种子填充算法分为两种,简单的和基于扫描线的方法,简单的算法如下描述(笔者针对的是二值图像): (1)从上到下,从左到有,依次扫描每个像素: ( ...
- C#程序员的春天之从零开始学习unity3D游戏开发入门教程二(创建项目及基本面板介绍)
一项目创建: 创建项目是开发的第一步. 运行untiy之后如果是第一次运行会弹出 我们这里随便创建一个项目. 二Untiy面板介绍: 三代码编辑器的切换: 这里我安装了vs2012. 到这里开发环境基 ...
- 如何在个人博客引擎 Hexo 中添加 Swiftype 搜索组件
在您现在看到的我的博客站点,后台使用的是 Hexo 作为博客引擎,但是默认集成的搜索组件是进行 form 提交到 Google 进行搜索的,为了更好地体验,本文介绍如何在 Hexo 博客中集成 Swi ...
- VUE --- 给页面加点网络动态数据
这时候的页面都是静态的(数据在写程序的时候已经固定了不能修改),而每个应用基本上都会请求外部数据以动态改变页面内容.对应有一个库叫 vue-resource 帮我们解决这个问题. 使用命令行安装 cn ...