如何快速从数据库加载100万条记录?

7

现在我们有一个包含100万条记录的Firebird数据库,必须在所有记录都加载到RAM内存后进行处理。为了获取所有记录,我们必须使用“select * first 1000 ...”语句提取数据长达8个小时。有什么解决方案吗?


表格的大小是多少?你确定你的内存可以容纳得下吗? - zs2020
2
听起来像是...世界上最快的数据库的工作! - Matt Ball
1
请发布您的while循环的完整代码 - s_hewitt
2
我认为你在做某些错误的事情...当我看到这样的模式时,通常意味着程序员/架构师没有完全理解如何在他们的设计中使用数据库。 - rmeador
2
根据上述指示需要更多信息。 - Romain Hippeau
显示剩余12条评论
5个回答

4

您描述的每个“select * first 1000”都会进行全表扫描吗?请查看这些查询,并确保它们使用索引。


不是选择速度的问题,而是从所选记录集到内存的数据传输,而while(read.Read())却需要太长时间... - Leonard P.

1
使用Firebird数据库在C#中从一个有100万行的表中加载数据,需要至少Pentium 4 3Ghz处理器8小时。大家都以为你是在运行SQL查询来从数据库中选择记录,就像这样:
select * 
from your_big_table
/

因为那确实只需要几秒钟。嗯,稍微长一点才能在屏幕上显示出来,但执行实际选择应该是闪电般快速的。

但你提到 C# 让我想你正在做其他事情。也许你真正拥有的是一个 RBAR 循环,实例化了一百万个对象。我可以看出这可能需要更长一些时间。但即便如此,八个小时?时间都去哪儿了?

编辑

我的猜测是正确的,你正在循环实例化 1000000 个对象。正确的建议是,在将所有对象加载到内存中后,找到其他方法实现所需操作。没有更多关于细节的了解,很难给出具体建议。但似乎这不是用户界面 - 哪个用户会浏览一百万个对象呢?

因此,一般性的观察就足够了:使用批量操作来实现批量活动。SQL 数据库擅长处理集合。利用 SQL 的强大功能,以单个集合而不是单个行处理您的一百万行。

如果您不认为这个答案有帮助,则需要提供更多有关您尝试实现的内容的详细信息。


我们的流程最坏情况下每月运行一次。是的,我们在一个大循环中加载所有表中的数据。那个循环是我们的瓶颈。我曾经考虑过制作一些数据库的克隆版本,并运行一些并行查询以更快地加载数据。 - Leonard P.
2
当你有那么多记录时,永远不要在循环中加载记录。这是数据库的基础知识。我不知道火鸟数据库,但大多数数据库支持在插入时使用选择语句,例如:insert table2 (field1, field2) select field1, field2 from table1这比逐行插入要快得多。 - HLGEM

1

每次数据读取创建DTO对象需要多长时间?

{ int a = read.GetInt32(0); int b = read.GetInt32(1); mylist.Add(new DTO(a,b)); }

你正在创建一百万个这些对象。如果创建一个DTO对象需要29毫秒,那么完成这个任务需要超过8小时。


0
你需要进行什么样的处理,才需要将它们加载到内存中而不是通过SQL语句进行处理?
我使用了两种技术,具体取决于我要做什么。
1. 假设有某种人工键(标识符),则按批处理工作,递增上次处理的最后一个标识符值。
2. 将数据BCP导出到文本文件中,通过更新进行处理,然后将其BCP导回,记得在IN步骤之前关闭约束和索引。

我们对数据库中的每个项目进行了一些分析,需要将它们加载到内存中。瓶颈在于从记录集转移数据到我们的DTO对象的时刻。 - Leonard P.

0

那个链接没有帮助我,也许这个问题在所有数据库上都会遇到。我需要优化“while (read.Read())”的时间。 - Leonard P.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接