科技知识动态:内存数据库FastDB和SQLite性能测评

导读跟大家讲解下有关内存数据库FastDB和SQLite性能测评,相信小伙伴们对这个话题应该也很关注吧,现在就为小伙伴们说说内存数据库FastDB和SQLi

跟大家讲解下有关内存数据库FastDB和SQLite性能测评,相信小伙伴们对这个话题应该也很关注吧,现在就为小伙伴们说说内存数据库FastDB和SQLite性能测评,小编也收集到了有关内存数据库FastDB和SQLite性能测评的相关资料,希望大家看到了会喜欢。

说是测评,其实过程也很简单,无非是设计测试CASE,编写测试CODE,输出测试RESULT,最后做出结论。通常我们认为带索引的插入耗时相对 于查询和删除来说比较长,因此首先来看插入性能。采用一个简单的表来完成接下来的所有测试,表中仅包含两个字段,INTEGER

说是测评,其实过程也很简单,无非是设计测试CASE,编写测试CODE,输出测试RESULT,最后做出结论。通常我们认为带索引的插入耗时相对 于查询和删除来说比较长,因此首先来看插入性能。采用一个简单的表来完成接下来的所有测试,表中仅包含两个字段,INTEGER intKey,和VARCHAR strKey。测试平台为Window7 32bit系统(Evaluation Copy 7127),编译器VC6 SP6。在DELL INSPIRON 640m上运行,CPU为Intel Core 2 CPU T5500 @ 1.66GHZ,内存2.5G。

对FastDB(采用磁盘模式),表结构的定义如下:

class _TestTable { public: db_int8 intKey; char const* strKey; TYPE_DESCRIPTOR((KEY(intKey, INDEXED), KEY(strKey, INDEXED))); };

REGISTER(_TestTable);

对SQLite,建表SQL如下:

CREATE TABLE [_TestTable] ( [intKey] INTEGER NOT NULL PRIMARY KEY, [strKey] VARCHAR(50) NULL)

2.2 不同事务模式下的插入性能比较

2.2.1 FastDB磁盘模式

我们首先按照批量事务处理的模式将intKey从1到nRecords(记录条数),并指定相应的strKey,分别调用相应的接口(均为原始 API)插入到两张表中,这里的批量事务处理模式指的是,比如插入10000条记录,插第一条之前开始事务,最后一条之后结束事务。此时在插入不同数目记 录时的表现分别如下(一万条、十万条、72万条、一百万条):

批量事务提交:

E:\intrest\FastDB\PerfTest\Debug>PerfTest.exe [FASTDB] Elapsed time for inserting 10000 record: 63 ms [SQLITE] Elapsed time for inserting 10000 record: 639 ms

E:\intrest\FastDB\PerfTest\Debug>del *.fdb (清除测试生成数据,重新测试,下同。)

E:\intrest\FastDB\PerfTest\Debug>PerfTest.exe [FASTDB] Elapsed time for inserting 100000 record: 1186 ms [SQLITE] Elapsed time for inserting 100000 record: 6318 ms

E:\intrest\FastDB\PerfTest\Debug>del *.fdb

E:\intrest\FastDB\PerfTest\Debug>PerfTest.exe [FASTDB] Elapsed time for inserting 7200000 record: 152460 ms [SQLITE] Elapsed time for inserting 7200000 record: 560121 ms

E:\intrest\FastDB\PerfTest\Debug>PerfTest.exe [FASTDB] Elapsed time for inserting 1000000 record: 15522 ms [SQLITE] Elapsed time for inserting 1000000 record: 67423 ms

从上我们可以看出,在批量事务模式下,FastDB比SQLite的插入性能提高了3-10倍。但是在很多情况下,我们可能会需要逐条逐条的事务提交,下面给出了逐条事务模式的测试结果:

E:\intrest\FastDB\PerfTest\Debug>PerfTest.exe [FASTDB] Elapsed time for inserting 10000 record: 57315 ms(这个太恐怖了,不调整的话没法使用) [SQLITE] Elapsed time for inserting 10000 record: 780 ms

E:\intrest\FastDB\PerfTest\Debug>PerfTest.exe (SQLITE显式分条事务) [FASTDB] Elapsed time for inserting 10000 record: 59967 ms [SQLITE] Elapsed time for inserting 10000 record: 1154 ms

从上我们可以看出,FastDB在这种情形下的性能急遽降低,降到一个几乎不能接收的水平。经过对FastDB的源代码分析(开源的好处体现出来 了),发现FastDB在每次事务提交时,都会将变更的数据内容同步到磁盘文件中(这是因为我们采用了磁盘模式),因此造成性能的显著降低。

直观上看,解决FastDB的这个问题有两种办法,一是避免每次事务提交时同步到磁盘,因为在这种应用中,这种同步操作并不需要实时进行,通常每隔 一段时间同步一次就可以了(比如1S、1Min、等根据具体项目的可靠性需要);二是使用前面提到的FastDB无盘(DISKLESS)模式。

我们首先来看第一种方案,通过SEARCH FastDB文档(文档和社区是FastDB的一个软肋),我们发现作者已经考虑到了这个问题,FastDB为数据库提供了precommit的接口,用 于完成除sync到磁盘文件外的所有事物操作,如释放mutex资源等。同时提供了backup接口,用来完成内存数据到磁盘文件的备份,甚至支持打开数 据库时同时指定定时备份到磁盘文件的间隔。这样一来,每次事务提交的效率理论上会得到大大提高,并且通过定时备份机制可以保证数据的可靠性。我们来看使用 precommit进行逐条事务提交时FastDB的表现:

E:\intrest\FastDB\PerfTest\Debug>PerfTest(使用precommit逐条提交事务) [FASTDB] Elapsed time for inserting 10000 record: 62 ms [SQLITE] Elapsed time for inserting 10000 record: 1170 ms

E:\intrest\FastDB\PerfTest\Debug>PerfTest [FASTDB] Elapsed time for inserting 100000 record: 1170 ms [SQLITE] Elapsed time for inserting 100000 record: 11747 ms

E:\intrest\FastDB\PerfTest\Debug>PerfTest [FASTDB] Elapsed time for inserting 1000000 record: 8081 ms [SQLITE] Elapsed time for inserting 1000000 record: 125768 ms

从上可以看出,在逐条事务模式下,通过使用precommit技术,FastDB性能比SQLite提高了10倍左右。当然也许有读者怀疑加了备份 机制之后的性能,确实笔者没有进行这项测试,但是,需要注意的是,FastDB在数据库关闭时会强制sync到磁盘文件,但SQLite没有这种功能,同 时,在进行这项测试时,两种数据库都没有定时备份机制,因此该比较是公平的。

2.2.2 FastDB无盘模式

再来看第二种方案,FastDB采用无盘(通过编译选项控制生成DISKLESS版本)模式,此时FastDB初始化一段共享内存(shmat or mmap),这个初始大小通常很大,并且运行期不能扩展(无盘模式的劣势)。我们将初始共享内存设置为1G,得到的测试结果如下:

E:\intrest\FastDB\PerfTest\Debug>PerfTest.exe [FASTDB] Elapsed time for inserting 100000 record: 624 ms (批量事务提交) [SQLITE] Elapsed time for inserting 100000 record: 11544 ms

E:\intrest\FastDB\PerfTest\Debug>PerfTest.exe [FASTDB] Elapsed time for inserting 100000 record: 7410 ms (逐条事务提交) [SQLITE] Elapsed time for inserting 100000 record: 11560 ms

E:\intrest\FastDB\PerfTest\Debug>PerfTest.exe [FASTDB] Elapsed time for inserting 1000000 record: 134660 ms [SQLITE] Elapsed time for inserting 1000000 record: 120167 ms

E:\intrest\FastDB\PerfTest\Debug>PerfTest.exe [FASTDB] Elapsed time for inserting 250000 record: 23666 ms [SQLITE] Elapsed time for inserting 250000 record: 29110 ms

从上我们可以看出,无盘模式在大数据量下的表现与SQLite相近,这一点不是很好理解,需要研究DISKLESS的设计模式,理论上应该与 precommit模式性能相近。但是实践是检验真理的唯一标准。我们可以看出,磁盘模式的precommit方式性能表现卓越,不管从横向还是纵向来 看。

2.3 查询性能比较

下面的比较都使用磁盘模式的precommit方式,再来看索引查询的性能表现,测试时都是先插入十万条数据后,再分别对该十万条数据进行查询,需 要注意的是我们同时对FastDB是否增加HASH索引的性能进行了横向测评,FastDB增加HASH索引很简单,通过修改TYPE- DESCRIPTOR来完成,上面的class中改为TYPE_DESCRIPTOR((KEY(intKey, INDEXED), KEY(strKey, INDEXED)));即为intKey增加了Hash索引。

E:\intrest\FastDB\PerfTest\Debug>perftest (FASTDB哈希索引) [FASTDB] Elapsed time for inserting 100000 record: 624 ms [FASTDB] Elapsed time for 100000 index searches: 328 ms [SQLITE] Elapsed time for inserting 100000 record: 10312 ms [SQLITE] Elapsed time for 100000 index searches: 10935 ms

E:\intrest\FastDB\PerfTest\Debug>perftest(FASTDB非哈希索引) [FASTDB] Elapsed time for inserting 100000 record: 577 ms [FASTDB] Elapsed time for 100000 index searches: 515 ms [SQLITE] Elapsed time for inserting 100000 record: 10343 ms [SQLITE] Elapsed time for 100000 index searches: 9532 ms

从测试结果可以看出,查询十万条索引记录的效率,FastDB要比SQLite快20倍左右,并且在增加HASH索引后能够得到进一步的改善。

2.4 删除性能比较及综合表现

最后,我们在测试删除效率时,同时综合来看FastDB与SQLite之间插入、查询、删除的性能表现:

插入、查询、删除综合比较:

E:\intrest\FastDB\PerfTest\Debug>perftest(批量删除,FASTDB.removeall(),SQLITE.delete*) [FASTDB] Elapsed time for inserting 100000 record: 608 ms [FASTDB] Elapsed time for 100000 index searches: 687 ms [FASTDB] Elapsed time for deleting all 100000 records: 16 ms [SQLITE] Elapsed time for inserting 100000 record: 11107 ms [SQLITE] Elapsed time for 100000 index searches: 10062 ms [SQLITE] Elapsed time for deleting all 100000 records: 16 ms

E:\intrest\FastDB\PerfTest\Debug>perftest(逐条删除) [FASTDB] Elapsed time for inserting 100000 record: 593 ms [FASTDB] Elapsed time for 100000 index searches: 562 ms [FASTDB] Elapsed time for deleting all 100000 records one by one: 905 ms [SQLITE] Elapsed time for inserting 100000 record: 10406 ms [SQLITE] Elapsed time for 100000 index searches: 10249 ms [SQLITE] Elapsed time for deleting all 100000 records one by one: 8923 ms

从上可以看出,就删除效率而言,批量删除的速度二者相近,而逐条删除时,十万条记录的删除累积,FastDB比SQLite快了10倍左右。

2.5 总结

优点:FastDB磁盘模式下,采用precommit方式,性能远远优于SQLite,并且FastDB提供了完善的备份恢复机制,能够保证数据 安全。FastDB的无盘模式在小数据量时表现优越,并且不会产生磁盘数据文件,也不能加载已经保存的数据库文件,看起来更像是针对嵌入式设备(如智能手 机、PDA等)开发的,对于这种场景可以考虑使用无盘模式。

缺点:FastDB目前能够SEARCH到的比较著名的应用是PingTel公司的开源统一通信产品SIPX,该产品采用的是FastDB的磁盘模 式。这可能多少与FastDB的完全授权模式有关,而SQLite采用的是GPL的不允许闭源的商业发布。当然主要还是社区的不成熟,这从Google Trends的搜索结果也能看出。社区的不成熟会带来学习成本的增加,这一点在选型时也需要考虑。

来源:php中文网

免责声明:本文由用户上传,如有侵权请联系删除!