0

我有一个带有 Customer 表的数据库。这些客户中的每一个都有一个安装表的外键,该表还有一个地址表的外键(为简单起见重命名表)。

NHibernate中,我尝试像这样查询 Customer 表:

ISession session = tx.Session;
var customers = session.QueryOver<Customer>().Where(x => x.Country == country);                               
var installations = customers.JoinQueryOver(x => x.Installation, JoinType.LeftOuterJoin);
var addresses = installations.JoinQueryOver(x => x.Address, JoinType.LeftOuterJoin);

if (installationType != null)
{
    installations.Where(x => x.Type == installationType);
}

return customers.TransformUsing(new DistinctRootEntityResultTransformer()).List<Customer>();

这导致类似于(由NHibernate Profiler捕获)的 SQL 查询:

SELECT *
FROM   Customer this_
       left outer join Installation installati1_
         on this_.InstallationId = installati1_.Id
       left outer join Address address2_
         on installati1_.AddressId = address2_.Id
WHERE  this_.CountryId = 4
       and installati1_.TypeId = 1

当我在Microsoft SQL Server Management Studio中执行上述 SQL 查询时,它会在大约 5 秒内执行,但会返回 ~200.000 条记录。然而,在运行代码时检索List需要花费大量时间。我已经等了10分钟没有任何结果。调试日志表明,由于对象层次结构,构造和启动了许多对象。有没有办法解决这个性能问题?

4

2 回答 2

1

我不确定您要做什么,但是通过任何 OR 映射器加载和保存 200000 条记录是不可行的。创建 200000 个对象将花费大量内存和时间。根据您要执行的操作,将它们加载到页面中或直接在数据库上进行更新查询(sp 或命名查询)可以修复您的性能。批处理可以通过以下方式完成:

criteria.SetFirstResult(START).SetMaxResult(PAGESIZE);
于 2013-03-11T12:32:31.527 回答
0

NHibernate Profiler 在持续时间列 x/y 中显示两次,其中 x 是执行查询的时间,而 y 是初始化对象的时间。第一步是确定问题出在哪里。如果查询很慢,请使用 SQL Profiler(假设为 SQL Server)将实际查询发送到数据库,并在 SSMS 中检查其性能。

但是,我怀疑您的问题可能是日志记录级别。如果您将日志记录级别设置为 DEBUG,NHibernate 将生成非常详细的日志,这将显着影响性能。

即使您可以让它在 200000 条记录中表现良好,但您无法以有意义的方式向用户显示。您应该使用分页/过滤来减小结果集的大小。

于 2013-03-11T13:33:19.073 回答