沉浮於各種檔案型資料庫 hsqldb h2 還是derby

iteye_18961發表於2010-03-20

原始發表時間: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相仿……這一步步似乎激動人心哦……但是沒有通過應用的實地考察,暫時無法下定論。


    通關本文沒有給出一個確切的結論,甚至沒有具體的測試結果資料,因為這些太依賴於環境,基本沒有參考價值。這裡只是想通過本文傳達一個觀點,任何新技術都得經過多種不同的角度來考察後,得出一個在一定環境中是否適用的結論。

相關文章