【发布时间】:2012-03-29 19:14:02
【问题描述】:
我已经评估了 NHibernate 和 ADO.NET 的性能。我创建了一个测试应用程序,它有一个包含 75,000 条记录的 Employee 表。当我尝试使用 NHibernate 获取数据时,它与 ADO.NET 相比非常慢,大约慢了 290%(大约)。
NHibenrnate 绑定 75,000 条记录的平均性能是 2535 毫秒。
ADO.net 绑定 75,000 条记录的平均性能为 867 毫秒。
我可以理解 NHibernate 是 ADO.NET 的包装器,但您不能为检索支付 300% 的价格
我们尝试了来自 Internet 的 NHibernate 优化技巧。这里有一些
- 无状态会话的使用
- 命名查询的使用
- 会话刷新
- 使用存储过程
- 使用重新编译选项
根据我的经验,在内存中构建对象时会消耗时间。此外,从 NHibernate 和探查器中的 SQL 触发的查询也存在差异。一次又一次执行没有任何区别
从员工中选择 ID、姓名、加入日期、出生日期、部门 ID、状态:持续时间 516 选择 this._ID 作为 ID2_0_,this_.Name 作为 Name2_0_,this_.DateOfJoin 作为 DateOfJoin2_0_,this_.DateOfBirth 作为 DateOfBirth2_0_,this_.DepartmentID 作为 DepartmentID2_0_,this_.Status 作为 Status2_0_ from dbo.Employee this_:持续时间 1538
请提出任何其他提高性能的机制。使用 ORM 时理想的性能差异应该是什么?
请在下面找到代码……
//Employee Class
public class Employee
{
public virtual int ID { get; set; }
public virtual string Name { get; set; }
public virtual DateTime DateOfJoin { get; set; }
public virtual DateTime DateOfBirth { get; set; }
public virtual string DepartmentID { get; set; }
public virtual string Status { get; set; }
}
//NHibernate Mapping
public EmployeeMap()
{
Table("Employee");
Id(p => p.ID).GeneratedBy.Increment();
Map(p => p. Name);
Map(p => p. DateOfJoin);
Map(p => p. DateOfBirth);
Map(p => p. DepartmentID);
Map(p => p. Status);
}
//Building Session Factory
public static ISessionFactory SessionFactory
{
get
{
if (_sessionFactory == null)
{
_sessionFactory = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008.ConnectionString(c => c.FromConnectionStringWithKey("Connection")))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Employee>())
.BuildSessionFactory();
}
return _sessionFactory;
}
}
//Fetching data using CreateQuey
using (IStatelessSession session = SessionManager.SessionFactory.OpenStatelessSession())
{
IList<Employee> lstEmployee = session.CreateCriteria< Employee >().List<Employee>();
return lstEmployees.ToList<Employee>();
}
//Fetching data using Create Query
using (IStatelessSession session = SessionManager.SessionFactory.OpenStatelessSession())
{
IList<Employee> lstEmployee = session.CreateQuery("from Employee "). List<Employee>();
return lstEmployees.ToList<Employee>();
}
//Fetching Data using ADO.net
DataTable dtEmployees = /*Data is fetched from ADO.net using SQL Query*/;
List<Employee> lstEmployee = new List<Employee>();
foreach (DataRow dr in dtEmployees.AsEnumerable())
{
Employee employee = new Employee
{
ID = dr.Field<int>("ID"),
Name = dr.Field<decimal>("Name"),
DateOfJoin = dr.Field<int>("DateOfJoin"),
DateOfBirth = dr.Field<int>("DateOfBirth"),
DepartmentID = dr.Field<int>("DepartmentID"),
Status = dr.Field<DateTime>("Status"),
};
lstEmployee.Add(Employee);
【问题讨论】:
-
您是否正在考虑构建会话工厂?同样在您上面的陈述中,您说 NHibernate 实际上更快(867 毫秒)。
-
你确定你测量的是你认为你测量的东西吗?您显示的两个查询完全相同相同(字段和表别名除外),我看不出它们如何导致 SQL 分析器中的执行时间出现这种差异。
-
另外请说明您使用的是哪个版本的 NHibernate。
-
您确定要在单个查询中获取 75 000 行吗?此外,您没有显示您正在测量的确切代码路径。您应该至少运行几次查询。然后去掉最慢和最快的时间并计算平均值。初始化静态值等可能需要很多时间,而且这些只会在第一次发生。
-
我们使用的是 NHibernate 3.1。抱歉,我现在修改了时间。
标签: performance nhibernate orm fluent-nhibernate