代码之家  ›  专栏  ›  技术社区  ›  Dave McClelland

处理庞大的SQL结果集

  •  9
  • Dave McClelland  · 技术社区  · 15 年前

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

    目前,我已经更改了查询,不返回图像。在迭代resultset时,我运行了另一个select,它获取与当前记录相关的单个图像。这是可行的,但是数以万计的额外查询导致了性能下降,这是不可接受的。

    我的下一个想法是将原始查询限制为10000个左右的结果,然后继续跨10000行进行查询。这似乎是两种方法之间的折衷。我觉得可能有一个更好的解决办法,我不知道。有没有其他方法一次只在内存中存储一个巨大结果集的一部分?

    干杯,

    4 回复  |  直到 15 年前
        1
  •  3
  •   Anthony Pegram    15 年前

    一种选择是使用数据读取器。它流式传输数据,但代价是保持与数据库的开放连接。如果您要迭代几百万行并对每一行执行处理,这可能是不可取的。

    我认为您正朝着正确的方向前进,可能是使用MySql的Limit方法来获取数据,对吗?

        2
  •  1
  •   Mark Byers    15 年前

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

    你也可以将图像设置为 DelayLoad = true 因此,只有在需要它们时才获取它们,而不是自己实现这个功能。看到了吗 here 更多信息。

        3
  •  0
  •   ProphetBeal    15 年前

    我有两个选择。

    1) 如果这是一个windows应用程序(与web应用程序相反),您可以使用数据读取器读取每个图像,并将文件转储到磁盘上的临时文件夹中,然后您可以对物理文件执行任何需要的处理。

    2) 读取并处理小块数据。10k行仍然可能很大,这取决于图像的大小以及您要执行的处理量。一次返回5k行,当剩下1k要处理时,在一个单独的线程中读取更多的行,可以实现无缝处理。

    另外,虽然并不总是推荐,但在处理下一组行之前强制垃圾收集有助于释放内存。

        4
  •  0
  •   Gary    15 年前

    http://www.asp.net/(S(pdfrohu0ajmwt445fanvj2r3))/learn/data-access/tutorial-25-cs.aspx

    您可以使用多线程来预拉接下来几个数据集的一部分(首先拉1-10000,在后台拉10001-20000和20001-30000行;并删除数据的前几页(例如,如果是50000到60000,则删除前1-10000行以节省内存,如果这是一个问题)。并使用用户当前“页面”的位置作为指针,来拉取下一个范围的数据或删除一些超出范围的数据。