【问题标题】:Query duration in NHibernate ProfilerNHibernate Profiler 中的查询持续时间
【发布时间】:2011-11-30 14:07:18
【问题描述】:

我有一个使用 Fluent NHibernate 访问 oracle 数据库的 ASP .Net MVC 应用程序。我还使用 NHibernate Profiler 来监控 NHibernate 生成的查询。我有一个非常简单的查询(从具有 4 个字符串列的表中选择所有行)。它用于创建 CSV 格式的报告。我的问题是查询需要很长时间才能运行,我想更深入地了解 nhprof 显示的持续时间。对于 65.000 行,它需要 10-20 秒,即使“仅数据库”持续时间仅显示 20 毫秒。这段时间网络延迟应该不会太大,因为服务器位于同一个千兆 LAN 上。我不希望人们能够为我准确指出瓶颈在哪里,但我想知道更多关于如何在 NHibernate 分析器中读取持续时间测量值的细节。

“仅数据库”部分包含哪些内容,“总时间”部分包含哪些内容?总时间是否还包括填充 C# 对象后完成的处理,所以这个时间实际上是针对整个 http 请求的?对此有更多了解有望使我能够消除一些因素。

NHibernate 映射类如下所示:

Table("V_TICKET_DETAILS");

CompositeId()
     .KeyProperty(x => x.TicketId, "TICKET_ID")
     .KeyProperty(x => x.Key, "COLUMN_NAME")
     .KeyProperty(x => x.Parent, "PARENT_NAME");

 Map(x => x.Value, "COLUMN_VALUE");

而nh profiler生成的查询是这样的:

SELECT this_.TICKET_ID    as TICKET1_35_0_,
       this_.COLUMN_NAME  as COLUMN2_35_0_,
       this_.PARENT_NAME  as PARENT3_35_0_,
       this_.COLUMN_VALUE as COLUMN4_35_0_
FROM   V_TICKET_DETAILS this_

视图非常简单,只需将两个表连接到一个 2 位整数上。

我绝不是数据库专家,所以我会为所有能够为我指明正确方向的 cmets 感到高兴。

【问题讨论】:

  • 你是只看,也更新,也拉相关,批量拉?
  • 我不是将数据插入数据库的人(另一个团队这样做),所以我不确定更新/插入是如何完成的。我认为他们会在新票进入系统时一一进行。如果这就是你的意思?
  • 关于获取:我确实分批获取 1000 张票的数据,但是 1000 张票意味着来自 V_TICKET_DETAILS 视图的 650.000 行,所以你可以说它是相当大的批量。如果我执行会更好将 650.000 行提取拆分成更小的批次?

标签: oracle nhibernate fluent-nhibernate profiling nhprof


【解决方案1】:

总时间仅用于调用 nHib 查询。
但是,除了数据库中的时间之外,它还包括 nHib 填充您的实体(水合作用)所需的时间。这可能是你的罪魁祸首。
我有a similar problem,也许那里的一些建议可能会对你有所帮助。

最重要的是,nHib 并不是真正打算加载大型数据集。
如果我得到的建议都没有帮助到你,我会建议几件事:
1. 您的用户不太可能需要同时查看 65,000 行数据。也许您可以找到一种过滤数据的方法,以使结果集更小(并且更具可读性)。
2. 否则-如您所说,如果它是仅在您生成报告时发生的“特殊”情况-您不必使用nHib。你可以使用,比如说,好的 ol' ADO.Net 类......

【讨论】:

  • 1:这是一个处理工单的系统,每个工单在 V_TICKET_DETAILS 视图中将有大约 65 行。当用户尝试针对 1000 多张工单生成 CSV 报告时,就会出现此问题。他们希望获得每张票的所有详细信息,因此有必要获取所有 65k 行。 2:是的,我认为你可能是对的,这对 nhib 来说不是一个好案例,所以我可能想改用 ADO.Net
  • 普通的旧 ADO.Net 在这种情况下完成了工作。不确定我是否会改用 IStatelessSession,但由于 Linq2NHibernate 似乎不支持它,所以无论如何我都必须更改我的数据访问实现。所以这次我选择了 ADO.Net 解决方案,因为性能是一个问题。
【解决方案2】:

还有IStatelessSession 用于这种情况。它没有会话缓存并节省了大量工作。应该会快很多。

using (var session = factory.OpenStatelessSession())
{
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 2012-11-22
    • 2011-10-07
    • 1970-01-01
    相关资源
    最近更新 更多