沉浮于各种文件型数据库 hsqldb h2 还是derby

原始发表时间:2009-09-10

 

    经过几天的折腾终于还是心碎了,前前后后为了这个数据库共计花费了约2周的时间……
    系统采用的是经典技术框架 Spring 2.0.5 + Hibernate 3.2 + iBatis 2.2.0
    用于连接文件型数据库的jdbc连接工具是ExecuteQuery 3.1.5(以下简称为EQ)
    数据库目前采用的是 hsqldb
    测试环境下准备了一个大小为33Mb的数据库命名为 test.script ,核心的是存放主要数据的资料表,主要结构如下:

create table Member_info(
    id char(32), employee_id char(32), employee_name varchar(50), company_id char(32), company_name varchar(50), ... ,
    user_def_txt0 varchar(50), user_def_txt1 varchar(50), ... , user_def_txt9 varchar(50),
    user_def_num0 number(8,2), user_def_num1 number(8,2), ... , user_def_num99 number(8,2)
)

    好了,一切准备就绪,开始说明一下为什么hsqldb和h2这么折腾我了吧!!

1.在这个应用里,hsqldb的内存模式和cached模式都不能用
    使用hsqldb的内存模式来读入数据,会发现连接数据库的时候奇慢无比,读了一下hsqldb的源代码,发现它在创建数据库连接的时候,会检查log文件、script文件的修改时间是否一致,而后查询网上hsqldb的开发者Thomas的话是说,也会检查properties文件中modified属性是否为yes,如果在退出应用的时候,没有执行shutdown,那么modified值肯定为yes,这样的话,下次连接数据库的时候,hsqldb会认为上次的退出是非法退出,需要根据log文件的内容从中断处进行恢复,并将这些未写入的数据继续写入到script数据文件中。
    具体执行过程时,先创建一个与script文件同名的后缀为.new的文件,比如数据文件为test.script,那么临时文件的名称为test.script.new,等数据写入完成后,删除原有的script文件,重命名.new的文件为test.script。
    目测这个转换的时间就很长……所以这里就不再给出具体的时间长度……

    使用 EQ 连接内存模式下的hsqldb,会发现连接速度也是挺慢……猜测是内存模式下,会将33Mb的数据全部都载入到内存,这个加载过程或许也在耽误着我们宝贵的时间……

    cached模式,使用EQ和应用连接数据库都是奇怪无比,而后进行应用中最常用的一个业务功能测试性能,这个业务功能根据几十个公式对库表中的某些数值字段进行计算,例如以下这些语句:

update member_info
set user_def_num0 = user_def_num1 + user_def_num2 + user_def_num3
where company_id = '123456'

update member_info
set user_def_num10 = user_def_num11 * 1.3 + user_def_num12
where company_id = '123456'

……

    测试的时候,涉及到的数据行数大约在800行左右,company_id 上有单独的索引,执行的速度上,内存模式非常的快,cached模式大约慢30%左右,还算可以接受……
    不过仔细观察cached模式下,hsqldb产生的后缀为.data的文件,会发现一个很可怕的事情——
    内存模式下,script大小为33Mb,转换为cached模式后,存放数据的文件是.data文件,大约为68Mb。使用上述的十多个sql语句执行计算之后,会发现.data文件大小变成了200Mb。
    观察应用程序占用的内存空间(还有虚拟内存空间),发现内存模式和cached模式不相上下……这和hsqldb中宣称的cached模式很省资源的说法大相径庭……

    因为纠结于这么大的data文件会不会有什么其他性能问题,所以想在计算完成后,执行“checkpoint defrag”来对数据库进行压缩,结果却让人无法接受——执行步骤基本与之前的重新连接内存模式的数据库一样,会先创建.new的文件,再删除原有data文件,而后重命名——这个过程耗时实在是太久了,大约需要1分钟多,基本上是无法接受的时间长度。

2.H2的性能堪忧
    还是挺感谢Thomas的热情回复,之前在google新闻组上发帖求助,许多朋友帮助,最热情的莫过于H2作者的Thomas,他同时也是hsqldb的作者。
    怀着对hsqldb的无比敬意,试用了H2,但是在上面的计算过程中遇到了无法逾越的性能问题,根据我的测试结果来看,上述计算过程在hsqldb中每条update语句耗时0.2秒,在H2中则需要大约2秒;于是我发帖求助是否存在设置问题,后来Thomas也做了测试,比我测试的结果性能要好一些,但是仍然有5倍以上的耗时差距,因此该应用也无法使用H2,因为我们不能让用户在计算过程上等待得太久!!

3.Derby
    现在时间是2009年9月11日0:29:52,刚刚将数据移植到Derby,在压缩稳定后,数据文件夹大小约为66Mb。
    使用 EQ 的连接速度也还不错,使用上述的update语句,单条执行的时间约为 0.2 秒跟hsqldb相仿……这一步步似乎激动人心哦……但是没有通过应用的实地考察,暂时无法下定论。


    通关本文没有给出一个确切的结论,甚至没有具体的测试结果数据,因为这些太依赖于环境,基本没有参考价值。这里只是想通过本文传达一个观点,任何新技术都得经过多种不同的角度来考察后,得出一个在一定环境中是否适用的结论。

你可能感兴趣的:(spring,数据结构,ibatis,HSQLDB,Derby)