IBatis性能幾點優化[已經完成]
IBatis on Oracle的性能優化
我們先主要看2個參數
1.defaultRowPrefetch of oracle
2.enhancementEnabled of IBatis
環境
1. Java HotSpot(TM) Server VM (build 1.5.0_12-b04, mixed mode)
Java HotSpot(TM) Server VM (build 1.6.0_05-b13, mixed mode)
2. Intel(R) Core(TM)2 CPU T7400 @ 2.16GHz L2 4M
3. JVM OPTION -Xms512m -Xmx1024m -XX:PermSize=96m
從數據庫中讀取10000行, 5列數據情況, Java Bean對象大約不到100個屬性。循環20次, 外加5次的贓數據。
A. defaultRowPrefetch=default enhancementEnabled=false/true 754ms/743ms
B. defaultRowPrefetch=50 enhancementEnabled=false/true 389ms/382ms
C. defaultRowPrefetch=100 enhancementEnabled=false/true 319ms/319ms
D. defaultRowPrefetch=200 enhancementEnabled=false/true 277ms/274ms
E. defaultRowPrefetch=500 enhancementEnabled=false/true 251ms/250ms
F. defaultRowPrefetch=1000 enhancementEnabled=false/true 242ms/238ms
G. defaultRowPrefetch=1000 enhancementEnabled=true 237ms(JAVA6)
H. defaultRowPrefetch=200 enhancementEnabled=true 271MS(JAVA6)
總結以上情況, 在數據行比較多的情況下, defaultRowPrefetch值的提高, 對於性能的影響是顯著的, 但是, 這個提升是犧牲很多內存爲代價的, 因此, 如果過高的defaultRowPrefetch值會導致內存比較緊張。 另外值得說明的是, 在一樣的參數前提下, JAVA6對於性能還是有一定的提升的。對於比較大的查詢, defaultRowPrefetch經驗值應該是200還是合理的。 另外, 對於enhancementEnabled選項帶來的收益, 相對來說比較少。 但是,對於高壓力的系統, 這是無IO等待下情況的代碼執行提高這些是非常值。
以上的測試數據列數比較少, 因此在JAVA BEAN的建立上是非常的節約時間的, 我們看看在差不多100個屬性的填充下的性能表現, 我們已經知道了defaultRowPrefetch帶來收益的經驗值。 因此, 我們設置defaultRowPrefetch=200.
A. defaultRowPrefetch=200 enhancementEnabled=false 1736ms
B. defaultRowPrefetch=200 enhancementEnabled=true 1721ms
C. defaultRowPrefetch=50 enhancementEnabled=true 1866ms
OK, enhancementEnabled繼續表明對性能的提升作用很小, 但是列的數據大小對性能的影響是非常大的。 但是, 我們無法確定這個時間是消耗在Java Bean 填充上 還是列讀取上。IBatis沒有具體的辦法測試。 不過, 在減少結果參數說明的情況下, 性能能得到明顯的提升, 我們還是可以斷定, JAVA BEAN的被聲明成結果映射的時候, 儘量減少結果映射的列,可以獲得很高性能的提升。 因此, 使用IBatis操作大量的數據的表, 建議只映射應該獲取到的數據, 而不是全部的列。 select * from db where... 你可以取需要的列到java bean. 總而言之: select * from db where... 這樣的形式對性能影響比 把所有的列映射到Java Bean 來的小! set bean property + ResultSet.getXXX(int index)的操作消耗了大部分的性能。
一些代碼片段:
數據原的定義
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass">
<value>oracle.jdbc.OracleDriver</value>
</property>
<property name="jdbcUrl">
<value>jdbc:oracle:thin:@10.0.0.1:1521:test</value>
</property>
<property name="properties">
<props>
<prop key="user">test</prop>
<prop key="password">test</prop>
<prop key="defaultRowPrefetch">50</prop>
</props>
</property>
</bean>
爲單個SQL查詢定義defaultRowPrefetch, 在IBatis的定義中爲fetchSize
<select id="MS-FIND-PublishedOffers-By-MemberId-Paged" resultMap="RM-OfferResult" fetchSize="200">
CGLIB增強定義
<settings cacheModelsEnabled="true" enhancementEnabled="true" lazyLoadingEnabled="false" maxRequests="3000" maxSessions="3000" maxTransactions="3000" useStatementNamespaces="false"/>
我們先主要看2個參數
1.defaultRowPrefetch of oracle
2.enhancementEnabled of IBatis
環境
1. Java HotSpot(TM) Server VM (build 1.5.0_12-b04, mixed mode)
Java HotSpot(TM) Server VM (build 1.6.0_05-b13, mixed mode)
2. Intel(R) Core(TM)2 CPU T7400 @ 2.16GHz L2 4M
3. JVM OPTION -Xms512m -Xmx1024m -XX:PermSize=96m
從數據庫中讀取10000行, 5列數據情況, Java Bean對象大約不到100個屬性。循環20次, 外加5次的贓數據。
A. defaultRowPrefetch=default enhancementEnabled=false/true 754ms/743ms
B. defaultRowPrefetch=50 enhancementEnabled=false/true 389ms/382ms
C. defaultRowPrefetch=100 enhancementEnabled=false/true 319ms/319ms
D. defaultRowPrefetch=200 enhancementEnabled=false/true 277ms/274ms
E. defaultRowPrefetch=500 enhancementEnabled=false/true 251ms/250ms
F. defaultRowPrefetch=1000 enhancementEnabled=false/true 242ms/238ms
G. defaultRowPrefetch=1000 enhancementEnabled=true 237ms(JAVA6)
H. defaultRowPrefetch=200 enhancementEnabled=true 271MS(JAVA6)
總結以上情況, 在數據行比較多的情況下, defaultRowPrefetch值的提高, 對於性能的影響是顯著的, 但是, 這個提升是犧牲很多內存爲代價的, 因此, 如果過高的defaultRowPrefetch值會導致內存比較緊張。 另外值得說明的是, 在一樣的參數前提下, JAVA6對於性能還是有一定的提升的。對於比較大的查詢, defaultRowPrefetch經驗值應該是200還是合理的。 另外, 對於enhancementEnabled選項帶來的收益, 相對來說比較少。 但是,對於高壓力的系統, 這是無IO等待下情況的代碼執行提高這些是非常值。
以上的測試數據列數比較少, 因此在JAVA BEAN的建立上是非常的節約時間的, 我們看看在差不多100個屬性的填充下的性能表現, 我們已經知道了defaultRowPrefetch帶來收益的經驗值。 因此, 我們設置defaultRowPrefetch=200.
A. defaultRowPrefetch=200 enhancementEnabled=false 1736ms
B. defaultRowPrefetch=200 enhancementEnabled=true 1721ms
C. defaultRowPrefetch=50 enhancementEnabled=true 1866ms
OK, enhancementEnabled繼續表明對性能的提升作用很小, 但是列的數據大小對性能的影響是非常大的。 但是, 我們無法確定這個時間是消耗在Java Bean 填充上 還是列讀取上。IBatis沒有具體的辦法測試。 不過, 在減少結果參數說明的情況下, 性能能得到明顯的提升, 我們還是可以斷定, JAVA BEAN的被聲明成結果映射的時候, 儘量減少結果映射的列,可以獲得很高性能的提升。 因此, 使用IBatis操作大量的數據的表, 建議只映射應該獲取到的數據, 而不是全部的列。 select * from db where... 你可以取需要的列到java bean. 總而言之: select * from db where... 這樣的形式對性能影響比 把所有的列映射到Java Bean 來的小! set bean property + ResultSet.getXXX(int index)的操作消耗了大部分的性能。
一些代碼片段:
數據原的定義
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass">
<value>oracle.jdbc.OracleDriver</value>
</property>
<property name="jdbcUrl">
<value>jdbc:oracle:thin:@10.0.0.1:1521:test</value>
</property>
<property name="properties">
<props>
<prop key="user">test</prop>
<prop key="password">test</prop>
<prop key="defaultRowPrefetch">50</prop>
</props>
</property>
</bean>
爲單個SQL查詢定義defaultRowPrefetch, 在IBatis的定義中爲fetchSize
<select id="MS-FIND-PublishedOffers-By-MemberId-Paged" resultMap="RM-OfferResult" fetchSize="200">
CGLIB增強定義
<settings cacheModelsEnabled="true" enhancementEnabled="true" lazyLoadingEnabled="false" maxRequests="3000" maxSessions="3000" maxTransactions="3000" useStatementNamespaces="false"/>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.