Java DB Derby Blobs上的性能问题&删除

时间:2009-05-21 15:13:36

标签: java performance jdbc derby

我在删除德比中的blob时遇到了性能问题,并且想知道是否有人可以提供任何建议。

这主要是在windows和solaris下使用10.4.2.0,虽然我也测试了新的10.5.1.1版本候选版(因为它有很多高手改变),但这没有显着差异。

问题是,对于包含许多大blob的表,删除单行可能需要很长时间(通常超过一分钟)。

我用一个小测试重现了这个,它创建了一个表,插入了几行不同大小的blob,然后将它们删除。

表模式很简单,只需:

create table blobtest(id DEFAULT生成的id整数为identity,b blob)

然后我创建了7行,其中包含以下blob大小:1024字节,1Mb,10Mb,25Mb,50Mb,75Mb,100Mb。

我已经阅读了blob,检查它们是否已正确创建并且尺寸正确。

然后使用sql语句删除它们(“从blobtest中删除id = X”)。

如果按照我创建的顺序删除行,删除单行的平均时间为:

1024字节:19.5秒

1Mb:16秒

10Mb:18秒

25Mb:15秒

50Mb:17秒

75Mb:10秒

100Mb:1.5秒

如果我以相反的顺序删除它们,删除单行的平均时间为:

100Mb:20秒

75Mb:10秒

50Mb:4秒

25Mb:0.3秒

10Mb:0.25秒

1Mb:0.02秒

1024字节:0.005秒

如果我创建七个小blob,删除时间都是瞬时的。

因此看起来删除时间似乎与表中行的总大小有关,而不是与要删除的blob的大小有关。

我已经进行了几次测试,结果似乎是可重复的。

那么,是否有人对性能有任何解释,以及有关如何解决或修复它的任何建议?它确实在生产环境中使用大blob很有问题......

4 个答案:

答案 0 :(得分:3)

据我所知, Derby只会将BLOB与其他数据库数据一起存储,因此您最终将BLOB拆分为大量单独的数据库页面文件。这种BLOB存储机制适用于ACID,适用于较小的BLOB(例如,图像缩略图),但会因较大的对象而崩溃。根据Derby文档,在操作BLOB时关闭自动提交也可以提高性能,但这只会到目前为止。

如果大型BLOB上的良好性能很重要,我强烈建议您迁移到H2或其他DBMS,并且BLOB必须保留在数据库中。您可以使用SQuirrel SQL客户端及其DBCopy插件直接在DBMS之间进行迁移(您只需将其指向Derby / JavaDB JDBC驱动程序和H2驱动程序)。我很乐意帮助完成这一部分,因为我自己就这样做了,而且并不高兴。

如果失败了,您可以将BLOB移出数据库并进入文件系统。为此,您需要用BLOB大小(如果需要)和位置替换数据库中的BLOB列(URI或平台相关的文件字符串)。创建新blob时,可以在文件系统中创建相应的文件。该位置可以基于给定目录,并附加主键。例如,您的数据库位于“DBFolder / DBName”中,并且您的blob进入“DBFolder / DBName / Blob”并且文件名为“BLOB_PRIMARYKEY.bin”或者其他。要编辑或读取BLOB,请在DB中查询该位置,然后直接读取/写入该文件。然后,如果更改,则将新文件大小记录到数据库。

答案 1 :(得分:3)

我遇到了同样的问题。

我发现当我执行DELETE时,derby实际上完全“读取”了大段文件。我使用Filemon.exe来观察它是如何运行的。

我的文件大小为940MB,只删除一行需要90秒。

我相信德比将表数据存储在一个文件里面。还有一些设计/实现错误会导致它读取所有内容,而不是使用适当的索引来执行。

我做批量删除而不是解决此问题。 我重写了我的程序的一部分。它是“id =?”在自动提交中。 然后我重写了很多东西,它现在“在一个交易中包含ID IN(?,.......?)”。

总时间减少到之后的1/1000。

我建议您可以添加“标记为已删除”的列,其中包含批量实际删除的计划。

答案 2 :(得分:1)

我确定这不是您想要的答案,但对于具有吞吐量要求的生产环境,我不会使用Java DB。 MySQL也是免费的,可以更好地处理您的需求。我认为你真的只是反对你所选择的解决方案的限制。

我通常只使用Derby作为测试用例,特别是当我的整个数据库可以很容易地放入内存时。 YMMV。

答案 3 :(得分:0)

您是否尝试过increasing the page size of your database

有关此内容的更多信息,请参阅Tuning Java DB手册中的相关信息。