【问题标题】:How to avoid OutOfMemoryException while loading large chunks of data from a database?从数据库加载大块数据时如何避免 OutOfMemoryException?
【发布时间】:2012-08-12 07:24:33
【问题描述】:

假设,我们有一个表,其中包含一些大的 text 字段,其中包含 jpg 文件的二进制数据。任务是从磁盘上的数据库中获取这些文件。所以,起初我决定做以下事情:

MyDataContext dc = new MyDataContext();
foreach(ImageTable t in dc.ImageTable.OrderBy(i=>i.Id))
{
    using (StreamWriter writer = new StreamWriter(new FileStream(string.Concat(t.Name,".jpg"), FileMode.CreateNew), Encoding.GetEncoding(1251)))
    {
          writer.Write(t.Data);
          writer.Close();
    }
}

但是当表格有大约 20000 行时,我很快就收到了OutOfMemoryException

最后,为了避免将所有行加载到一个数据上下文中,我做了以下操作:

MyDataContext dc = new MyDataContext();
foreach(int id in dc.ImageTable.OrderBy(i=>i.Id).Select(i=>i.Id))
{
     using (MyDataContext _dc = new MyDataContext())
     {
           ImageTable t = _dc.ImageTable.FirstOrDefault(i => i.Id == id);
           using (StreamWriter writer = new StreamWriter(new FileStream(string.Concat(t.Name,".jpg"), FileMode.CreateNew), Encoding.GetEncoding(1251)))
           {
                writer.Write(t.Data);
                writer.Close();
           }
      }
}    

所以每一行都由一个单独的数据上下文加载...没有内存问题! 但这肯定不是完成任务的最佳方法。

谁能给点建议?

【问题讨论】:

  • 创建一个新的数据上下文是一个轻量级的操作,所以这不是什么大问题。话虽这么说,像支出者提到的那样关闭对象跟踪是正确的解决方案。
  • 首先,你需要20000行数据干什么???其次,为什么将 jpgs 存储在数据库中? “你可以”这一事实并不意味着“你应该”。
  • 我不在那里存储图片...一些公司软件会...我的任务是将它们从数据库中取出以导入其他系统...所以,显然所有的行必须导出到磁盘)

标签: c# linq linq-to-sql sql-server-2000 out-of-memory


【解决方案1】:

您可以尝试关闭object tracking

_dc.ObjectTrackingEnabled = false;

【讨论】:

    【解决方案2】:
    1. 如果它已经有效:解决内存问题,性能满足您的应用程序的需求,这是一个很好的解决方案

    2. 如果您仍然对结果不满意,您可以考虑离开linq to sql 并查看raw SQL 使用SqlDataReader只读, forward only 光标,在读取操作中获得最大效率。

    希望这会有所帮助。

    【讨论】:

    • Linq-To-Sql 对性能有影响,但如果使用得当,对内存不足错误影响不大。
    • @Tigran 虽然这是一项一次性任务,而且任务确实完成了,但我使用 ObjectTrackingEnabled = false 对其进行了测试......就是这样!当我解决我的内存问题时,我(完全忘记了 ObjectTracking)明白一个 simlpe DataReader 可以解决问题,但无论如何用 L2S 来做这件事对我来说更快。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-07
    • 1970-01-01
    • 2010-10-22
    • 2012-10-06
    相关资源
    最近更新 更多