是什么减缓了数据库性能的增长?

时间:2008-10-10 21:25:53

标签: database batch-file insert scalability

我正在创建一个数据库,并首先进行原型设计和基准测试。我正在使用H2,一个开源的,商业免费的,可嵌入的,关系型的java数据库。我目前没有索引任何专栏。

数据库增长到大约5GB后,其批处理写入速度加倍(写入速度减慢了原始速率的2倍)。我使用一个新的,干净的数据库写入大约每行25行,现在是7GB,我写的大约是7行/ ms。我的行由short,int,float和byte [5]组成。

我对数据库内部甚至H2的编程知之甚少。我还要注意,我并没有贬低H2,因为这是我测试的其他DBMS的一个问题。

如果没有索引开销,哪些因素可能会减慢数据库速度?它主要与文件系统结构有关吗?根据我的结果,我假设Windows XP和ntfs处理文件的方式使得在文件增长时将数据附加到文件末尾的速度变慢。

9 个答案:

答案 0 :(得分:2)

随着数据库的增长,可能使插入变得复杂的一个因素是表上的索引数,以及这些索引的深度(如果它们是B树或类似的)。还有更多的工作要做,可能是你导致索引节点分裂,或者你可能只是从5级B树转移到6级B树(或者更常见的是,从N到N + 1级别。)

另一个因素可能是磁盘空间使用 - 如果你使用的是熟文件(大多数时候这对大多数人来说都是正常的;有些DBMS在Unix上使用'原始文件',但你的嵌入式系统不太可能这样做,你知道它是否因为你必须告诉它这样做了,可能是你的大表现在在磁盘上碎片化,导致性能更差。

如果问题出在SELECT性能上,可能还有许多其他因素也会影响系统的性能。

答案 1 :(得分:2)

这听起来很对。数据库性能通常会显着下降,因为数据不再保留在内存中,操作变为磁盘绑定。如果您使用正常的插入操作,并希望显着提高性能,我建议使用某种批量加载API,如果H2支持它(如Oracle sqlldr,Sybase BCP,Mysql'加载数据infile')。这种类型的API将数据直接写入数据文件,绕过许多数据库子系统。

答案 2 :(得分:1)

这很可能是由可变宽度字段引起的。我不知道H2是否允许这样做,但在MySQL中,你必须创建包含所有固定宽度字段的表,然后将其显式声明为固定宽度字段表。这允许MySQL准确计算数据库文件中需要进行插入的位置。如果您没有使用固定宽度表,那么它必须通读表来查找最后一行的结尾。

附加数据(如果正确)是一个O(n)操作,其中n是要写入的数据的长度。它不依赖于文件长度,有搜索操作可以轻松跳过它。

答案 3 :(得分:1)

对于大多数数据库,追加到数据库文件肯定比预先生成文件然后添加行要慢。看看H2是否支持预生成文件。

答案 4 :(得分:0)

另一个原因是整个数据库是否保存在内存中,或者操作系统是否必须进行大量磁盘交换才能找到存储记录的位置。

答案 5 :(得分:0)

我会把它归咎于I / O,特别是如果你在普通硬盘上使用普通硬盘运行你的数据库(我的意思是不是在带有超快速硬盘的服务器上等)。

答案 6 :(得分:0)

许多数据库引擎为每次更新创建一个隐式整数主键,因此即使您没有声明任何索引,您的表仍会被编入索引。这可能是一个因素。

答案 7 :(得分:0)

从技术角度来看,将H2用于7G数据文件是一个错误的选择。如你所说,嵌入式。如果您需要存储如此多的数据,那么您拥有什么样的“嵌入式”应用程序。

答案 8 :(得分:0)

您是否正在执行增量提交?由于H2是符合ACID的数据库,如果您没有执行增量提交,那么有一些类型的重做日志,以便在出现意外故障(例如断电)或回滚的情况下,可以回滚删除。 / p>

在这种情况下,您的重做日志可能会变得越来越大并且内存缓冲区溢出,并且需要将重做日志写入磁盘以及实际数据,从而增加了I / O开销。