C++ C/C的数据库写入与磁盘I/O++;

C++ C/C的数据库写入与磁盘I/O++;,c++,c,io,bigdata,disk-io,C++,C,Io,Bigdata,Disk Io,因此,我正在为一个新项目生成一个工作流。在第一阶段,将有一个C/C++代码生成大量数据(基于测试用例的二进制文件格式约1TB)。然后将这些数据导入数据库,以便与驻留在那里的另一个数据集进行比较 我的问题是,打开数据库软件的端口并直接写入,或者磁盘写入许多小文件(约10亿个)并稍后导入数据库,会更快吗?C代码将在有时间限制的集群上运行,因此需要快速完成 您没有指定正在运行的数据库,因此理论上答案可能是任何东西。然而,在实践中,现代硬盘驱动器速度很慢:它们的写入速度大约为100 MB/s。通常,如果

因此,我正在为一个新项目生成一个工作流。在第一阶段,将有一个C/C++代码生成大量数据(基于测试用例的二进制文件格式约1TB)。然后将这些数据导入数据库,以便与驻留在那里的另一个数据集进行比较


我的问题是,打开数据库软件的端口并直接写入,或者磁盘写入许多小文件(约10亿个)并稍后导入数据库,会更快吗?C代码将在有时间限制的集群上运行,因此需要快速完成

您没有指定正在运行的数据库,因此理论上答案可能是任何东西。然而,在实践中,现代硬盘驱动器速度很慢:它们的写入速度大约为100 MB/s。通常,如果要向数据库插入大量数据,这是一个限制因素。计算机中的RAM没有帮助,因为1TB无法装入RAM。但是,您可能需要使用特定于数据库的技巧,例如在单个事务中添加所有数据,或者可能需要预处理一次编译并多次调用的查询。如果您使用的是固态磁盘(SSD),答案可能会有所不同,但这取决于SSD的速度

请注意,网络接口可能会限制添加性能。千兆链路实际上意味着略低于125 MB/s。因此,如果数据库位于另一台计算机上,则网络接口性能可能是限制因素。但是,如果在同一台计算机上生成数据或使用万兆链路,则网络链路性能不太可能成为限制因素

但是,唯一确定的答案是在您的环境中测试它。如果绩效对你很重要,那么一定要学习标杆管理的艺术


这个表有索引吗?如果是这样,那么先插入数据,然后在插入所有数据后才建立索引可能会提高性能。

您必须对此进行测试才能知道


不同的数据库产品以不同的速度运行,我们不知道数据库的硬件,如果真的大数据上有很多索引,它可能会使一切变慢。

虽然正确的答案应该是“这取决于,你需要衡量”,但在这种情况下,可以给出一个不合格的答案,并具有可接受的确定性:

直接与数据库服务器对话几乎肯定会更快

原因不仅在于,在通过网络发送数据之前,先将数据写入磁盘,然后再读取数据,这会增加磁盘驱动器的延迟和带宽限制(这是不可避免的,因为每个文件在页面缓存中至少占用一个页面,10亿个文件——即使每个文件只有1字节的内容——占用至少4TB的缓冲区,因此不会有缓存).4TB数据的读取需要3-5个小时,假设在快速磁盘上进行顺序读取。虽然由于延迟写回,写入磁盘实际上可能主要是顺序进行的,但几乎可以保证在发送数据之前再次读取数据不会是连续的(并且不存在提前读取的情况,对于不同的文件不可能)。如果幸运的话,有些操作可能仍然会重叠,隐藏它们的延迟——但总而言之,这并不是“免费的”

诚然,您可能会受到数据库接受请求的能力或网络带宽的限制,但即使不添加额外副本,您也会受到限制,至少前者是您可以轻松优化的。您可以将数据插入到数据库中,而无需任何索引,这将是非常困难的非常快。数据库服务器随后可以创建您以后可能需要的任何索引。这当然可能需要一些时间,但可能比每次更新都更新索引快一个数量级(此外,谁在乎,如果重要的是您有限的时间工作完成得快的话)


然而,更重要的是,仅仅打开和关闭以及重新打开10亿个文件需要非常明显的时间(这包括遍历目录层次结构、名称到索引节点的转换以及访问检查等),并且访问单个文件所花费的时间将是非常疯狂的。即使在没有物理“搜索”发生的固态磁盘上,随机访问时间也不是“零”(它们要小得多,但是0.1ms乘以10亿仍然需要在搜索上多花费近3个小时!).

我不认为编写中间文件的速度会更快,因为您最终必须将它们写入数据库。唯一确保这两个文件都写入并对其进行基准测试的方法是。这是一个非常模糊的问题,它取决于数据的结构、与数据库的连接类型、数据库的类型、,SSD/HDD的类型和文件系统这一决策的一部分将取决于数据库软件的位置和特性。您应该将系统的简单模型和接口作为起点。我的第一印象是,管理数百万个小文件将带来许多只有我们才会感到头疼的问题对数据库系统进行加密可以消除11亿个文件?这是降低性能的好方法。1000个怎么样?