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的搜索結果也能看出。社區的不成熟會帶來學習成本的增加,這一點在選型時也需要考慮。
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com