使用C#从Oracle检索超过1000万条记录

10

我有一个包含超过1亿条记录的数据库。我正在运行一个包含超过1000万条记录的查询。这个过程需要太长时间,因此我需要缩短这个时间。我想将我的获取记录列表保存为csv文件。请问如何以最快和最优的方式完成?期待您的建议。谢谢。


4
请发布表结构、现有查询和 C# 代码的详细信息。同时说明对于您的情况,“太多时间”的具体含义是什么。性能主要取决于上下文。 - Alex Norcliffe
1
同时发布您选择数据的标准...这可能会影响表分区、索引等。 - Adam Houldsworth
5
为什么你需要展示或导出如此多的数据?最终用户真的会阅读或分析1000万条记录吗?与其只提供通常的解决方案并满足客户要求,我建议你应该询问客户的业务需求或最终需求,并根据其进行工作。 - Tathagat Verma
还有其他事情:你的文件格式是固定的吗?目标是什么?请记住,即使在Excel 2007及以后版本中打开CSV文件,Excel也不能(据我所知)处理1000万行。在2007年之前,限制是65000(!)行。 - Alex Norcliffe
@TathagatVerma:99%的CSV生成是关于将数据发送到另一个应用程序/系统。 - Clement Herreman
@ClementHerreman:也许吧,但是一个有1000万条记录的CSV文件!!这只是不现实,并试图通过短暂的解决方案来实现短期目标。 - Tathagat Verma
4个回答

12

我假设您的查询已经限制到了您需要的行/列,并且充分利用了索引。

在这个规模下,唯一关键的是不要一次性将所有内容加载到内存中,因此请忘记诸如DataTable和大部分完整的ORM(通常会尝试将行与身份管理器和/或更改管理器相关联)等东西。您必须使用原始的IDataReader(来自DbCommand.ExecuteReader),或者在其上构建一个非缓冲迭代器的任何API(有几种选择;我比较偏向Dapper)。为了编写CSV文件,原始数据读取器可能就足够了。

除此之外:由于带宽受限,您无法让它运行得更快。唯一能加速的方式是在数据库服务器上创建CSV文件,以便没有网络开销。


5
机会很小,你不需要使用C#来完成这项任务。这是批量数据加载/导出的领域(通常用于数据仓库方案)。
许多(免费)工具(我想甚至包括Quest Software的Toad)将比您在任何平台上编写的更加稳健和高效。
我有一个预感,您实际上不需要这个终端用户(简单的观察是部门秘书实际上不需要邮寄副本;它太大而无法以这种方式使用)。
我建议使用正确的工具来完成工作。无论您做什么,请注意以下几点:
- 不要自己制定数据类型转换 - 使用带引号的CSV并考虑转义其中的双引号 - 考虑区域选项(即:始终使用InvariantCulture进行导入/导出!)

“将更加牢固且高效地完成此操作,超越您在任何平台上编写的方式。”这些工具你认为是用什么编写的呢?如果它们不在数据库引擎上运行,那么它们将使用相同的协议来获取数据。除非相关要点是“超越您的编写能力” :) - Alex Norcliffe
@AlexNorcliffe:你懂了!在我不那么谦虚的观点中,有合适经验水平的程序员是不会问这个问题的。 - sehe
2
我变得更加谦虚了。如果我要重新写那个评论,我不会感到有必要那么直截了当地表达。将其保留下来,以便我们可以看到人们的学习历程。 - sehe

3
这个过程包括三个子过程:
1.检索> 10m条记录 2.将记录写入文件 3.在网络上传输记录(我假设您正在使用本地客户端对远程数据库进行操作)
其中任何一个或所有这些问题都可能成为瓶颈。因此,如果要减少总经过时间,您需要确定时间花费在哪里。您可能需要使用C#代码来获取指标。
如果查询是问题,则需要对其进行调整。索引在这里无法帮助,因为您正在检索表的大块(> 10%),因此提高全表扫描的性能将有所帮助。例如,增加内存以避免磁盘排序。并行查询可能很有用(如果您拥有企业版并且具有足够的CPU)。还要检查问题是否是硬件问题(主轴争用,不良互连等)。
写入文件可能是问题吗?也许您的磁盘由于某种原因而变慢(例如碎片),或者您正在与其他进程竞争写入相同的目录。
在网络上传输大量数据显然是潜在的瓶颈。您确定只向客户端发送相关数据吗?
另一种替代架构:使用PL / SQL将记录写入数据服务器上的文件,使用bulk collect检索可管理的记录批次,然后在最后通过FTP将文件传输到所需位置,可能首先进行压缩。

1

真正的问题是为什么需要从数据库中读取这么多行数据(以及底层数据集的如此大比例)。有许多方法可以避免这种情况,其中明显的方法包括同步处理、消息队列和预先整合。

暂且不谈这个问题…如果你正在整合数据或者筛选数据,那么将大部分逻辑实现在PL/SQL中可以避免通过网络传输数据(即使只是本地主机,仍然存在很大的开销)。同样,如果你只想将其导出到平面文件中,用C#实现也没有什么好处。


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