用c#列出来自Oracle的超过1000万条记录
本文关键字:1000万 记录 Oracle | 更新日期: 2023-09-27 18:16:06
我有一个包含超过1亿条记录的数据库。我正在运行一个包含超过1000万条记录的查询。这个过程花费了太多的时间,所以我需要缩短这个时间。我想将获得的记录列表保存为csv文件。我怎样才能做得越快越好?期待您的建议。谢谢。
我假设你的查询已经被限制到你需要的行/列,并且很好地利用了索引。
在这种规模下,唯一关键的是不要一次将所有的加载到内存中;因此,忘记DataTable
和大多数完整的orm(它们通常尝试将行与身份管理器和/或更改管理器相关联)之类的东西吧。你必须使用原始的IDataReader
(来自DbCommand.ExecuteReader
),或者任何在顶部上构建非缓冲迭代器的API(有几个;我更喜欢衣冠楚楚。对于编写CSV的目的,原始数据阅读器可能很好。
除此之外:你不能让它跑得更快,因为你的带宽有限。您可以更快地获得它的唯一方法是在数据库服务器
上创建CSV文件,这样就没有网络开销。在c#中这样做的可能性很小。这是批量数据加载/导出的领域(通常用于数据仓库场景)。
许多(免费的)工具(我想甚至是Quest Software的Toad)会比你在任何平台上写的都更健壮、更有效。
我有一种预感,你实际上并不需要最终用户(简单的观察是,部门秘书实际上不需要邮寄副本;它太大了,不能用那种方式使用。
我建议使用合适的工具。无论你做什么
- 不要进行自己的数据类型转换
- 使用带引号的CSV,并考虑转义这些 中的双引号
- 考虑区域选项(low:总是使用InvariantCulture进行导出/导入!)
"这个过程花费太多时间,所以我需要缩短这个时间。"
该过程由三个子过程组成:
- 检索> 10m记录
- 写入记录到文件
- 通过网络传输记录(我的假设是您正在与本地客户端对远程数据库工作)
这些问题中的任何一个或所有问题都可能成为瓶颈。因此,如果您想减少总运行时间,您需要弄清楚时间花在哪里。你可能需要编写你的c#代码来获得这些指标。
如果结果显示查询是问题所在,那么您需要对其进行调优。索引在这里没有帮助,因为您正在检索表的大块(> 10%),因此提高全表扫描的性能将有所帮助。例如,增加内存以避免磁盘排序。并行查询可能很有用(如果您有Enterprise Edition并且有足够的cpu)。还要检查问题不是硬件问题(主轴争用,可疑的互连等)。
写入文件是问题吗?也许您的磁盘由于某些原因(例如碎片)很慢,或者您正在与其他向同一目录写入的进程竞争。
在网络上传输大量数据显然是一个潜在的瓶颈。你确定你只向客户发送相关数据吗?
另一种架构:使用PL/SQL将记录写入数据服务器上的文件,使用批量收集检索可管理的记录批次,然后通过FTP将文件传输到您需要的位置,可能首先压缩它。
真正的问题是为什么需要从数据库中读取这么多行(以及这么大比例的底层数据集)。有很多方法可以避免这种情况,最明显的是同步处理、消息队列和预整合。
先不说这个…如果您正在整合数据或筛选数据,那么在PL/SQL中实现大部分逻辑可以节省通过网络传输数据的时间(即使只是传输到本地主机,也会有很大的开销)。同样,如果你只是想把它转储到一个平面文件中,在c#中实现它不会给你带来任何好处。