我有一个要求,我必须选择大约6000万和记录从数据库。一旦我有了ResultSet中的所有记录,我就必须根据客户需求(日期格式和数字格式)格式化一些列,然后我必须将所有记录写入一个文件中(辅助内存)。
请建议这个场景的最佳设计,我是否应该使用一些缓存机制,如果是,那么哪一种和如何?
注意:客户端不想在数据库中更改任何东西,比如创建索引或存储过程,他们不想接触数据库。提前谢谢。
发布于 2009-05-18 16:39:14
你是否需要在内存中保存所有的记录来格式化它们?您可以尝试将记录通过一个进程并通过该文件的权限进行流。如果您能够进一步分解查询,则可以开始处理结果,同时仍然可以检索结果。
根据您的DB后端,它们可能有一些工具来帮助这一点,例如用于Server 2005+的SSIS。
编辑
我是一个.net开发人员,所以让我建议一下我将在.net中做些什么,希望您能够在java端转换成类似的技术。
ADO.Net有一个DataReader,它是一个结果集的前向只读游标。它在执行查询时返回数据。这一点非常重要。基本上,我的逻辑是:
IDataReader reader=GetTheDataReader(dayOfWeek);
while (reader.Read())
{
file.Write(formatRow(reader));
}因为这是在我们返回行时执行的,所以您不会阻止网络访问,我猜这对您来说是一个巨大的瓶颈。这里的关键是,我们不会在内存中保存很长时间,因为我们循环读取器会丢弃结果,并且文件会将行写入磁盘。
发布于 2009-05-18 17:08:21
我觉得乔什的意思是:
您有循环,当前遍历查询的所有结果记录(这里只使用伪代码):
while (rec = getNextRec() )
{
put in hash ...
}
for each rec in (hash)
{
format and save back in hash ...
}
for each rec in (hash)
{
write to a file ...
}
instead, do it like this:
while (rec = getNextRec() )
{
format fields ...
write to the file ...
}那么你一次记忆中的记录就不会超过一张.你可以处理无限数量的记录。
发布于 2009-05-18 17:39:08
很明显,一次读取六千万张唱片会消耗你所有的记忆--所以你不能这么做。(你的7线程模型)。一次读六千万张唱片会消耗你所有的时间--所以你也不能这样做(即你的初始读取到文件模型)。
所以..。你得妥协,两者兼而有之。
乔希的方法是正确的-打开一个光标到你的数据库,简单地读取下一个记录,一个接一个,以最简单、最具特色的方式。“消防软管”游标(也称为只读、前向游标)是您在这里想要的,因为它对数据库施加的负载最少。DB将不允许您更新记录,也不允许您在记录集中后退,因为无论如何您都不需要这样做,因此它不需要处理记录的内存。
现在您有了这个游标,数据库每次给您一条记录--读取它,并将它写入一个文件(或多个文件),这应该很快就会完成。然后,您的任务是按照正确的顺序将文件合并到1中,这相对容易。
考虑到您需要处理的记录数量,我认为这是您的最佳解决方案。
但是..。既然您目前做得很好,那么为什么不减少线程的数量,直到您在内存限制之内。批量处理是一夜之间运行的许多公司,这似乎只是另一个过程之一。
https://stackoverflow.com/questions/878583
复制相似问题