5000 万条记录中的内存不足 c# nhibernate

Posted

技术标签:

【中文标题】5000 万条记录中的内存不足 c# nhibernate【英文标题】:Out Of Memory in 50 million record c# nhibernate 【发布时间】:2017-01-27 00:55:07 【问题描述】:

如何在 5000 万条记录 nhibernate 中处理 Out Of Memory,我在 NHibernate 中使用了无状态会话并解决了大约 170 万条记录,但这对我的报告不利。 另一件事是我需要计算它们,所以我不能分解结果。 你能告诉我如何优化它吗?

        public IEnumerable<ATMDispenseReport> GetReport(string WhereClause)
    

        var CurrentUnitOfWork = this.UnitOfWork as MainUnitOfWork;

        var session = CurrentUnitOfWork.StatelessSession;

        string SqlQuery = "MyQuery";

        var lstATMDispenseReport =session.CreateSQLQuery(SqlQuery)       .SetResultTransformer(Transformers.AliasToBean<ATMDispenseReport>())
            .List<ATMDispenseReport>();

        return lstATMDispenseReport;
    

编辑:最终解决方案是使用 DBMS 来处理查询计算。

【问题讨论】:

您能否举例说明您的数据是什么样的以及您想要计算什么?也许有一种方法可以在数据库站点上进行计算,由您的 sql 查询中的适当聚合启动。 ORM 中的“O”代表对象。对象有bevahour。报告没有对象,因为它们没有任何行为。即使您坚持使用 ORM 进行报告,也无法创建包含 170 万行的报告——没有人(或机器)能够使用它。你想做什么?在 RAM 中加载 170 万行不会使报表比仅返回最终报表数据的 SQL 语句更快 50M 记录是一个非常非常强烈的指标,表明您需要一个适当的报告架构和一个适当的 ETL 流程来填充它。 感谢 Patrick 和 Panagiotis Kanavos :) @PanagiotisKanavos 你认为有 2 个数据表来加载 1600 万和 800 万数据是个好主意吗? 【参考方案1】:

我假设您在 x86(32 位)上运行。 .NET 中的数组(或 List&lt;T&gt;)必须存储在连续的内存块中,因此 5000 万个项目的列表将需要超过 200MB 的单个块来存储 @987654323 的每个实例的地址@(这会在多次实例化后发生,因为列表是动态增长的)。

虽然 32 位应用程序有 2GB 的内存限制,但如果您已经有一堆东西并且内存是零散的,那么您可能没有足够大的连续区域。然后你还有 5000 万个 ATMDispenseReport 对象,它们不需要连续分配,但它们可能至少比 4 字节指针大 10 倍。

    肮脏的黑客?切换到 x64 并检查这台机器是否有足够的 RAM。你可能也需要&lt;gcAllowVeryLargeObjects&gt;。请注意,对于平均大小约为 40B 的对象,您将需要超过 2GB 的 RAM。这对于单个查询来说似乎有点奇怪,因为我怀疑您的用户是否真的需要一次所有这些行。

    简单的解决方案?如果您确实需要枚举所有结果,请将List&lt;T&gt;() 替换为Enumerable&lt;T&gt;() 并枚举结果。这将懒惰地流式传输数据,因此您只需要随时在内存中保留一个元素。但是请记住,所有这些数据仍然需要通过您的应用程序用来连接到 DBMS 服务器的套接字传递。我们可能正在谈论几 GB 的数据。

    更好的解决方案?重写您的 SQL 以在 SQL 端聚合所有数据,然后再返回到您的应用程序。让 DBMS 服务器完成所有工作。

【讨论】:

非常感谢 Groo,我在这篇文章之前尝试了解决方案 1,但效果不佳,但我认为解决方案 2 解决了我的问题。

以上是关于5000 万条记录中的内存不足 c# nhibernate的主要内容,如果未能解决你的问题,请参考以下文章

在 python 中高效处理约 5000 万条记录文件

如何从 RODBC 读取 300 万条记录并写入文本文件

Laravel 迁移 - 为 5000 万条数据添加新列

Java用POI导出excel时出现内存不足的问题,测试数据数量为:13万条,已经实现了,每六万条条数据时

如何使用 Laravel 的块来避免内存不足?

C 中针对 100 万条记录的数组的内存优化