[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)慢查询 ...
随机推荐
- InfluxDB学习之InfluxDB的HTTP API查询操作
在 InfluxDB学习 的上一篇文章:InfluxDB学习之InfluxDB的HTTP API写入操作 中,我们介绍了使用InfluxDB的HTTP API进行数据写入操作的过程,本文我们再来介绍下 ...
- Xamarin.Android VSTS 持续集成
这些天做了一个基于 VSTS 的 Xamarin.Android的持续集成,这里分享下 Build Agent 环境需求 DotNetFramework msbuild visualstudio An ...
- 帆软报表FineReport SQLServer数据库连接失败常见解决方案
1. 问题描述 帆软报表FineReport客户端连接SQLServer(2000.2005等),常常会出现如下错误:com.microsoft.sqlserver.jdbc.SQLServerExc ...
- winform记事本(基本功能)
本题主要考察各种控件的应用 using System; using System.Collections.Generic; using System.ComponentModel; using Sys ...
- webpack中alias别名配置
resolve:{ alias:{ bootcss:__dirname + '/node_modules/.3.3.7@bootstrap/dist/css/bootstrap.min.css' } ...
- nginx下目录浏览及其验证功能配置记录
工作中常常有写不能有网页下载东西的需求,在Apache下搭建完成后直接导入文件即可达到下载/显示文件的效果;而Nginx的目录列表功能默认是关闭的,如果需要打开Nginx的目录列表功能,需要手动配置, ...
- sqlite常用查询
做的小工具用到了sqlite,在查询上较sqlserver还是稍有差异,将常用操作汇总一下,慢慢收集和整理. --查询版本SELECT sqlite_version() AS 'SQLite Vers ...
- 简单CSS3实现炫酷读者墙
如题,给大家介绍和讲解几个常用的CSS3属性,并用到实处. 先看demo(请使用Chrome或者Firefox浏览,IE的靠边): 点此查看实例 觉得爽的可以继续阅读下面的知识点,感觉不爽的可绕行. ...
- Dell xps 13 9350待机时总是关机的处理方法
现象: 年初买的dell xps13 9350,最近可能是由于win10做了一些更新,每次睡眠就自动关机了,重启很多次,修改电源选项都没用, 原因分析: 在网上搜了一下,有人发现xps15 9350也 ...
- [CareerCup] 6.6 Toggle Lockers 切换锁的状态
6.6 There are 100 closed lockers in a hallway. A man begins by opening all 100 lockers. Next, he clo ...