我正在使用一个相当大的mysql数据库(几百万行),其中有一列存储blob图像。应用程序试图获取图像的一个子集,并对它们运行一些处理算法。我遇到的问题是,由于我拥有的数据集相当大,我的查询返回的数据集太大,无法存储在内存中。
目前,我已经将查询更改为不返回图像。在迭代结果集时,我运行了另一个select,它捕获与当前记录相关的单个图像。这是可行的,但成千上万的额外查询导致了不可接受的性能下降。
我的下一个想法是将原始查询限制在10,000个结果左右,然后在10,000行的范围内继续查询。这似乎是两种方法之间的折中。我觉得可能有一个更好的解决方案,我不知道。有没有其他方法可以一次只在内存中存储一个巨大结果集的一部分?
干杯
戴夫·麦克莱兰
4条答案
按热度按时间a2mppw5e1#
一种选择是使用DataReader。它可以流式传输数据,但代价是保持与数据库的连接处于打开状态。如果您要迭代数百万行并对每一行执行处理,则可能不理想。
我认为您正在沿着正确的道路获取数据块,可能使用MySql的Limit方法,对吗?
7xzttuei2#
当处理如此大的数据集时,重要的是不需要一次将所有数据都存储在内存中。如果您要将结果写入磁盘或网页,请在读取每一行时执行此操作。不要等到读取所有行后才开始写入。
你也可以将图片设置为
DelayLoad = true
,这样它们就只在你需要的时候才被获取,而不是自己实现这个功能。更多信息请参见here。jhdbpxl93#
我看到两个选择。
1)如果这是一个windows应用程序(而不是web应用程序),您可以使用数据读取器读取每个图像,并将文件转储到磁盘上的临时文件夹,然后您可以对物理文件进行任何需要的处理。
2)以小块的方式读取和处理数据。根据图像的大小和您想要处理的数据量,10k行仍然可能很大。一次返回5k行,当您剩下1k行时,在单独的线程中阅读更多行,可以实现无缝处理。
另外,虽然并不总是推荐,但在处理下一组行之前强制进行垃圾回收有助于释放内存。
t3psigkw4#
我以前使用过类似于本教程中概述的解决方案: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行以节省内存)。并使用用户在当前“页”的位置作为指针来拉取下一个数据范围或删除一些超出范围的数据。