hibernate的速度問題--hibernate.jdbc.fetch_size和 hibernate.jdbc.batch_size

hibernate的速度問題


      這點我也疑惑過,最初應用hibernate的項目,我也感覺速度很慢,知道後來才知道問題的所在。 
      其實hibernate的速度性能並不差,比起jdbc來說,又是性能能高2倍。 
      當然了這和應用的數據庫有關,在Oracle上,hibernate支持hibernate.jdbc.fetch_size和 hibernate.jdbc.batch_size,而MySQL卻不支持,而我原來的項目絕大多數都是使用MySQL的,所以覺得速度慢,其實在企業級應用,尤其是金融系統大型應用上,使用Oracle比較多,相對來說,hibernate會提升系統很多性能的。

 

hibernate.jdbc.fetch_size 50 //讀

hibernate.jdbc.batch_size 30 //寫

 

hiberante.cfg.xml(Oracle ,sql server 支持,mysql不支持)

   <property name="hibernate.jdbc.fetch_size">50</property>
<property name="hibernate.jdbc.batch_size">30</property>

這兩個選項非常非常非常重要!!!將嚴重影響Hibernate的CRUD性能!

 

C = create, R = read, U = update, D = delete

 

Fetch Size 是設定JDBC的Statement讀取數據的時候每次從數據庫中取出的記錄條數。

 

例如一次查詢1萬條記錄,對於Oracle的JDBC驅動來說,是不會1次性把1萬條取出來的,而只會取出Fetch Size條數,當紀錄集遍歷完了這些記錄以後,再去數據庫取Fetch Size條數據。

 

因此大大節省了無謂的內存消耗。當然Fetch Size設的越大,讀數據庫的次數越少,速度越快;Fetch Size越小,讀數據庫的次數越多,速度越慢。

 

這有點像平時我們寫程序寫硬盤文件一樣,設立一個Buffer,每次寫入Buffer,等Buffer滿了以後,一次寫入硬盤,道理相同。

 

Oracle數據庫的JDBC驅動默認的Fetch Size=10,是一個非常保守的設定,根據我的測試,當Fetch Size=50的時候,性能會提升1倍之多,當Fetch Size=100,性能還能繼續提升20%,Fetch Size繼續增大,性能提升的就不顯著了。

 

因此我建議使用Oracle的一定要將Fetch Size設到50

 

不過並不是所有的數據庫都支持Fetch Size特性,例如MySQL就不支持

 

MySQL就像我上面說的那種最壞的情況,他總是一下就把1萬條記錄完全取出來,內存消耗會非常非常驚人!這個情況就沒有什麼好辦法了 :(

 

Batch Size是設定對數據庫進行批量刪除,批量更新和批量插入的時候的批次大小,有點相當於設置Buffer緩衝區大小的意思。

 

Batch Size越大,批量操作的向數據庫發送sql的次數越少,速度就越快。我做的一個測試結果是當Batch Size=0的時候,使用Hibernate對Oracle數據庫刪除1萬條記錄需要25秒,Batch Size = 50的時候,刪除僅僅需要5秒!!!

//
我們通常不會直接操作一個對象的標識符(identifier), 因此標識符的setter方法應該被聲明爲私有的(private)。這樣當一個對象被保存的時候,只有Hibernate可以爲它分配標識符。 你會發現Hibernate可以直接訪問被聲明爲public,private和protected等不同級別訪問控制的方法(accessor method)和字段(field)。 所以選擇哪種方式來訪問屬性是完全取決於你,你可以使你的選擇與你的程序設計相吻合。

所有的持久類(persistent classes)都要求有無參的構造器(no-argument constructor); 因爲Hibernate必須要使用Java反射機制(Reflection)來實例化對象。構造器(constructor)的訪問控制可以是私有的(private), 然而當生成運行時代理(runtime proxy)的時候將要求使用至少是package級別的訪問控制,這樣在沒有字節碼編入 (bytecode instrumentation)的情況下,從持久化類裏獲取數據會更有效率一些。 而

hibernate.max_fetch_depth 設置外連接抓取樹的最大深度

取值. 建議設置爲03之間

就是每次你在查詢時,會級聯查詢的深度,譬如你對關聯vo設置了eager的話,如果fetch_depth值太小的話,會發多很多條sql

發佈了6 篇原創文章 · 獲贊 12 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章