处理巨大的SQL结果集

时间:2010-03-26 00:03:30

标签: c# .net mysql ado.net

我正在使用一个相当大的mysql数据库(数百万行),其中一列存储blob图像。该应用程序尝试获取图像的子集并在其上运行一些处理算法。我遇到的问题是,由于我拥有相当大的数据集,我的查询返回的数据集太大而无法存储在内存中。

目前,我已将查询更改为不返回图像。迭代结果集时,我运行另一个选择,它抓取与当前记录相关的单个图像。这有效,但成千上万的额外查询导致性能下降是不可接受的。

我的下一个想法是将原始查询限制为10,000个结果左右,然后继续查询超过10,000行的跨度。这似乎是两种方法之间的道路妥协。我觉得可能有一个我不了解的更好的解决方案。是否有另一种方法只能在内存中同时拥有巨大的结果集部分?

干杯,

Dave McClelland

4 个答案:

答案 0 :(得分:3)

一种选择是使用DataReader。它流式传输数据,但这是以保持与数据库的开放连接为代价的。如果您正在迭代数百万行并对每个行执行处理,那可能并不理想。

我认为你正朝着正确的方式抓住数据,可能是使用MySql的Limit方法,对吗?

答案 1 :(得分:1)

在处理如此大的数据集时,重要的是不需要一次将所有数据集全部存储在内存中。如果要将结果写入磁盘或网页,请在每行读取时执行此操作。在开始写作之前,不要等到你读完所有行。

您还可以将图像设置为DelayLoad = true,这样只有在您需要时才会获取图像,而不是自己实现此功能。有关详细信息,请参阅here

答案 2 :(得分:0)

我看到两个选项。

1)如果这是一个Windows应用程序(而不是Web应用程序),您可以使用数据读取器读取每个图像并将文件转储到磁盘上的临时文件夹,然后您可以执行所需的任何处理物理文件。

2)以小块的形式读取和处理数据。 10k行仍然可以很多,具体取决于图像的大小和您想要做多少处理。一次返回5k的行并在剩下1k的处理时在单独的线程中读取更多行可以实现无缝过程。

虽然并不总是建议,但在处理下一组行之前强制进行垃圾回收可以帮助释放内存。

答案 3 :(得分:0)

我之前使用过本教程中概述的解决方案: http://www.asp.net/(S(pdfrohu0ajmwt445fanvj2r3))/learn/data-access/tutorial-25-cs.aspx

你可以使用多线程来预拉下一些数据集的一部分(首先拉1-10,000,在后台拉10,001 - 20,000和20,001-30,000行;并删除前面的数据页(如果这是一个问题,如果您在50,000到60,000之间删除前1-10,000行以节省内存。)并使用当前“页面”的用户位置作为指针来提取下一个数据范围或删除一些数据范围数据。