【问题标题】:Exception 'System.OutOfMemoryException' in system.dllsystem.dll 中的异常“System.OutOfMemoryException”
【发布时间】:2013-12-09 10:32:11
【问题描述】:

我正在尝试选择表中包含大约 250 万条记录的所有列。

但它在执行一段时间后抛出了上述异常。如何解决这个问题

adapter.SelectCommand = new SqlCommand("SELECT * from Dwh_staging_table", con1);
adapter.Fill(DataSet2, "Transformed_Table");

【问题讨论】:

  • 整个数据对于允许应用程序分配的内存来说太大了。也许您可以通过逐行读取而不是一次加载所有行来解决问题。您真的需要加载表格的所有列吗?
  • 你能在数据库管理工具中执行同样的查询吗?
  • 可能只是部分加载您的数据
  • 是的,我需要阅读所有行..
  • 然后你需要对加载的数据做什么?

标签: c# sql sql-server-2008 optimization


【解决方案1】:

使用自定义分页。一次只获取有限的记录

【讨论】:

    【解决方案2】:

    我猜您正在处理一些自定义构建数据仓库解决方案,这意味着大量数据。无论您尝试做什么,都不应该将所有数据从数据库加载到应用程序来计算临时表中的一些数字。

    您可以做的最好的事情是在将数据放入 Dwh_staging_table 之前计算您需要的任何内容,以便在问题发生之前解决问题。如果这是不可能的并且您已经将数据加载到数据库中,您应该在数据库中进行所有处理(例如使用讨厌的存储过程)。

    一般来说,当您处理大量数据时,移动数据是您最大的敌人。尽量在数据所在的地方解决所有问题,避免不必要的转移。

    如果您无论如何都想将数据加载回 c# 代码(我不建议这样做),请尝试在不将所有数据具体化到内存中的情况下进行所有操作。创建返回 IEnumerable 的存储库函数,该函数将在内部使用 yield return,因此永远不会实现整个数据集合。

    如果您仍然坚持在某些集合中实现数据(我不建议更多),请查看一些不使用顺序内存块的集合。使用数组、列表或数据集等集合将导致内存不足异常的可能性更高。尝试使用 LinkedList 之类的东西,甚至更好地使用一些分块的 LinkedList 数组(几乎就像其他帖子中建议的分页一样)。

    编辑: 根据你说的

    我在表中有一些缺失值,我想在之后使用平均技术填充一些列

    对我来说,这听起来像是仅通过数据库中临时表的一个 UPDATE 语句就可以实现的事情。不确定您到底想要什么(例如,我想设置为按类别列分组的 Metric 列的 AvgMetric 平均值)。在这种情况下,它看起来像:

    WITH t AS (
    SELECT st.[Category]
          ,st.[AvgMetric]
          ,AVG(st.[Metric]) OVER (PARTITION BY [st.Category] AS [CalculatedAvgMetric]
      FROM [Dwh_staging_table] st
    )
    UPDATE t
       SET [AvgMetric] = [CalculatedAvgMetric]
    

    【讨论】:

    • 分页是与sql查询还是c#有关,我是这个概念的新手。
    • HaurkurHaf 建议使用 row_number() (beyondrelational.com/modules/2/blogs/28/posts/10434/…) 在 SQL 查询级别进行分页。优点是您只需将小块数据加载到内存中。缺点是您将对数据库执行多个查询。我的建议是在处理流中的所有数据时打开连接并保持打开状态。使用 LinkedList(或 LinkedList of Lists)是为了将所有内容都放在内存中。
    【解决方案3】:

    显而易见的答案是减少返回的数据集。您需要所有列吗?

    如何分页数据?查看 row_number() 函数。

    【讨论】:

    • 如何减少返回的数据集??
    • 您正在通过“选择 * ...”选择 所有 列。如果您不需要所有列,只需在 select 语句中指定您需要的列。尽管如此,我们仍然在谈论 250 万条记录,您正试图将它们放入内存中。通过使用 row_number() 函数,您可以将其拆分为批次,首先获取前 1000 行,然后是接下来的 1000 行,以此类推。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-12
    • 1970-01-01
    • 1970-01-01
    • 2015-09-04
    • 1970-01-01
    相关资源
    最近更新 更多