【问题标题】:NHibernate PerformanceNHibernate 性能
【发布时间】:2014-02-03 14:13:58
【问题描述】:

如果它是一个更复杂的对象并且数据库中已经有一些数据,那么使用 NHibernate 获取 + 删除一个对象非常慢。

示例:
- ObjectA(数据库中大约有 150.000 个条目) - ObjectB 引用 ObjectA(数据库中大约有 200.000 个条目) - ObjectC(与 ObjectA 的一对一关系) - ObjectD(与 ObjectC 的多对一关系,大约 800.000 个条目)

删除 ObjectA 也会删除上面列出的所有其他对象。 删除 100 个 ObjectA 大约需要 12 秒。可能是什么问题,NHibernate 这么慢?

如果我在一个空数据库上删除相同数量的对象,只需要大约 1-2 秒。

我已经尝试在大约 20 - 30 个对象后刷新 + 清除我的会话,但这并没有太大的区别。

【问题讨论】:

    标签: c# nhibernate fluent-nhibernate


    【解决方案1】:

    使用 NHibernate 删除 100 个对象会比直接执行 DELETE 语句(在空数据库上)要慢。在将对象转换为 C# 实体期间,总会有一些开销。

    但是 NHibernate 为这些场景提供了很好的解决方案,当我们需要删除数十个对象时 - 无需将它们加载到应用程序中:DML

    13.3. DML-style operations 的摘录

    ...因此直接在数据库中操作(使用 SQL 数据操作语言 (DML) 语句:INSERT、UPDATE、DELETE)数据不会影响内存状态。然而,NHibernate 提供了通过 Hibernate 查询语言 (HQL) 执行的批量 SQL 样式 DML 语句执行的方法。

    文档中的代码示例:

    ISession session = sessionFactory.OpenSession();
    ITransaction tx = session.BeginTransaction();
    
    string hqlDelete = "delete ObjectA a where a.property = :someValue";
    
    int deleteddEntities = s.CreateQuery( hqlDelete )
       .SetString( "someValue", someValue)
       .ExecuteUpdate();
    
    tx.Commit();
    session.Close();
    

    我们在 HQL 语句中拥有对映射属性的完全访问权限。但是该语句直接在数据库引擎上执行...

    【讨论】:

    • 我已经以这种方式执行删除操作,但是当我查看我的 SQL Profiler 时,即使我执行了这样的“批量”删除,NHibernate 也会将其转换为单个查询。删除一些关键约束(这远非最佳),我能够获得一些性能改进,但我仍在努力解决这个问题。
    • 好吧,请你仔细检查我的答案。请。因为 DML 确实有点不同。它不是对加载的对象进行操作,而是一种直接执行 DELETE 语句的方式。如果您可以创建条件,它将针对所有 100 个对象 - 肯定只有 1 个 DELETE 语句。它永远不会转换为单个查询...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-09
    • 1970-01-01
    • 2012-11-29
    • 1970-01-01
    • 1970-01-01
    • 2012-03-29
    相关资源
    最近更新 更多