【问题标题】:IEnumerable Collection - Out of Memory ExceptionIEnumerable 集合 - 内存不足异常
【发布时间】:2018-09-07 07:39:01
【问题描述】:

我的 C# 控制台应用程序中有代码查询 SQL 中的 LARGE 数据集,并将其添加到 IEnumerable 集合中,以便稍后在应用程序中进行迭代。在返回少于 100K 行的 SQL 表上,它工作得很好,但我必须使用它来遍历 1 亿条记录,在 SQL 查询运行后,Dapper 尝试填充集合,我最终会出现 OUT OF MEMORY异常错误。我很确定这是因为它试图一次写入 1 亿个对象。有没有一种方法可以批量处理不超过 500K 个对象的集合,做我需要做的事情然后回来处理另一个 500K 等等?我基本上需要从 SQL 500K 记录中读取,然后将它们写入文件,读取另一个 500K,写入另一个文件。

    public List<AxDlsd> GetDistinctDlsdObjects(AxApp axApp, OperationType operationType)
    {

        if (operationType == OperationType.Assessment)
        {

            string query = $"SELECT DISTINCT(clipid) from {axApp.dlname}";
            using (var connection = _dbConnectionFactory.GetAxDbConnection())
            {
                //SqlMapper.Settings.CommandTimeout = 0;
                List<AxDlsd> dlsdrecord = new List<AxDlsd>();

                return connection.Query<AxDlsd>(query, commandTimeout: 0, buffered: false ).ToList();

            }
        }

【问题讨论】:

  • 您的查询中的数据行太多,内存无法全部承载。
  • 哦,不要使用 .ToList(),它可能会导致查询运行完全创建您的对象,从而导致 buffered: false 无效。
  • Dapper. Paging的可能重复
  • 一开始就尝试将所有这些加载到内存中可能是一个错误。如果您有 1 亿条记录,请让数据库完成它的工作并自行响应搜索。仅仅通过网络将 100M 行从数据库移动到您的应用程序将花费比数据库处理 sql 语句并返回目标结果更长的时间。

标签: c# ienumerable


【解决方案1】:

您可以通过SELECT COUNT(DISTINCT clipid) from {axApp.dlname} 获取总数,然后使用它来分页

int pageSize = 500000;

for(var page = 0; page < (total / pageSize) + 1; page++)
{
    string query = $"SELECT DISTINCT(clipid) from {axApp.dlname} ORDER BY clipid OFFSET {page * pageSize} FETCH NEXT {pageSize} ROWS ONLY";
    ///...
}

这将允许您一次浏览 500k 行或任何您的页面大小。 FETCH/OFFSET 确实需要 SQL Server 2012。我不确定您使用的是什么 SQL。

【讨论】:

  • 我正在运行 SQL Server 2012 SP2,尝试在我的应用程序中运行上述查询时出现错误: System.Data.SqlClient.SqlException: '0' 附近的语法不正确。 FETCH 语句中选项 NEXT 的使用无效。'
  • page = 0 在你的例子中,所以 0 * 500,000 是 0
  • 对,你希望页面在前 500k 行查询中为 0,然后它将为 1,下一个将抓取 500,001 到 100 万行。
  • OFFSET 是要跳过多少条记录,而 FETCH 是要检索多少条记录,所以在第一次查询时,您要跳过 0 条记录并抓取 500k。在第二个查询中,您想要跳过 500k 记录并获取下一个 500k 等。
  • @MikeGen18 更新了我的答案,您需要在查询中添加按剪辑的顺序。
猜你喜欢
  • 2011-05-26
  • 1970-01-01
  • 2010-10-05
  • 1970-01-01
相关资源
最近更新 更多