JDBC優化策略總結
相比Hibernate、iBatis、DBUtils等,理論上JDBC的效能都超過它們。JDBC提供更底層更精細的資料訪問策略,這是Hibernate等框架所不具備的。
在一些高效能的資料操作中,越高階的框架越不適合使用。這裡是我在開發中對JDBC使用過程中一些優化經驗總結。
1、選擇純Java的JDBC驅動。
2、使用連線池–使用一個“池”來管理JDBC連線,並精心除錯池配置的引數,目前可用的資料庫連線池很多很多。
如何配置合適的引數呢,需要的是測試,而不是感覺。
3、重用Connection–最大限度使用每個資料庫連線,得到了就不要輕易“丟棄”。
有時候在一個過程中,會多次運算元據庫,而僅僅需要一個連線就夠了,沒必用一次就獲取一個連線,用完後關閉或者入池。這樣會增加“池”管理的成本,千萬別以為你用了“池”就可以隨便申請和歸還連線,都是有代價的。如果是一個龐大迴圈塊中運算元據庫,更應該注意此問題!
除此之外,還應該對連線進行密集使用,儘可能晚的開啟,並可能早的關閉。比如,你一個業務中有N多的操作,資料庫操作穿插在其中,而其他的業務處理操作時間很長,那麼使用一個連線處理這些操作是有問題的。這會導致長期佔用連線,給資料庫帶來壓力。
4、重用Statement/PreparedStatement–對於一些預定義SQL,設定為靜態常量,並儘可能重用預定義SQL產生的PreparedStatement物件。對於多次使用一種模式的SQL,使用預定義SQL可以獲取更好的效能。對於Statement物件,可以反覆的重用,每次都可以接收不同的SQL語句,而對於PreparedStatement則不可以,因為預定義SQL在定義PreparedStatement物件時候已經確定了,但是如果sql語句不變,則可以呼叫clearParameters()來達到從用目的,如果sql語句發生變化,也可以從用變數名。
5、使用批處理SQL。
6、優化結果集ResultSet–查詢時候,返回的結果集有不同的型別,優先選擇只讀結果集、不可滾動的屬性。
這裡是很容易出現問題的地方:
java.sql.ResultSet
static int CLOSE_CURSORS_AT_COMMIT
該常量指示呼叫 Connection.commit 方法時應該關閉 ResultSet 物件。
static int CONCUR_READ_ONLY
該常量指示不可以更新的 ResultSet 物件的併發模式。
static int CONCUR_UPDATABLE
該常量指示可以更新的 ResultSet 物件的併發模式。
static int FETCH_FORWARD
該常量指示將按正向(即從第一個到最後一個)處理結果集中的行。
static int FETCH_REVERSE
該常量指示將按反向(即從最後一個到第一個)處理結果集中的行處理。
static int FETCH_UNKNOWN
該常量指示結果集中的行的處理順序未知。
static int HOLD_CURSORS_OVER_COMMIT
該常量指示呼叫 Connection.commit 方法時不應關閉 ResultSet 物件。
static int TYPE_FORWARD_ONLY
該常量指示指標只能向前移動的 ResultSet 物件的型別。
static int TYPE_SCROLL_INSENSITIVE
該常量指示可滾動但通常不受其他的更改影響的 ResultSet 物件的型別。
static int TYPE_SCROLL_SENSITIVE
該常量指示可滾動並且通常受其他的更改影響的 ResultSet 物件的型別。
static int CLOSE_CURSORS_AT_COMMIT
該常量指示呼叫 Connection.commit 方法時應該關閉 ResultSet 物件。
static int CONCUR_READ_ONLY
該常量指示不可以更新的 ResultSet 物件的併發模式。
static int CONCUR_UPDATABLE
該常量指示可以更新的 ResultSet 物件的併發模式。
static int FETCH_FORWARD
該常量指示將按正向(即從第一個到最後一個)處理結果集中的行。
static int FETCH_REVERSE
該常量指示將按反向(即從最後一個到第一個)處理結果集中的行處理。
static int FETCH_UNKNOWN
該常量指示結果集中的行的處理順序未知。
static int HOLD_CURSORS_OVER_COMMIT
該常量指示呼叫 Connection.commit 方法時不應關閉 ResultSet 物件。
static int TYPE_FORWARD_ONLY
該常量指示指標只能向前移動的 ResultSet 物件的型別。
static int TYPE_SCROLL_INSENSITIVE
該常量指示可滾動但通常不受其他的更改影響的 ResultSet 物件的型別。
static int TYPE_SCROLL_SENSITIVE
該常量指示可滾動並且通常受其他的更改影響的 ResultSet 物件的型別。
說明下:
結果集分兩種型別:只讀和可更改,只讀的話,更省記憶體,查詢的結果集不能更改。如果結果集在查詢後,更改了值又要儲存,則使用可更改結果集。
結果集的遊標也有兩種型別:如果沒必要讓遊標自由滾動,則選擇單方向移動的遊標型別。
對於是否併發操作:如果不需要考慮執行緒安全,則選擇忽略併發的結果集型別,否則選擇併發安全的型別。
另外,還要控制結果的大小,幾乎所有的資料庫都有查詢記錄條數控制的策略,可以海量資料進行分批處理,一次一批,這樣不至於把系統搞死。
7、事物優化–如果資料庫不支援事物,就不要寫回滾程式碼,如果不考慮事物,就不要做事務的控制。
8、安全優化–管理好你的Connection物件,在異常時候能“入池”或者關閉。因此應該將Connection釋放的程式碼寫在異常處理的finally塊中。
9、異常處理優化–不要輕易吞噬SQLException,對於DAO、Service層次的資料訪問,一般在DAO中跑出異常,在Service中處理異常。但DAO中也可以處理異常,並做轉義丟擲,不要隨便丟擲RuntimeExeption,因為這是JVM丟擲的,不需要你可以去丟擲,因為RuntimeException往往會導致系統掛起。
10、程式碼高層優化–在以上的基礎上,優化封裝你的資料訪問方式,儘可能讓程式碼簡潔好維護,如果你還覺得效能不行,那就該從整個系統角度考慮優化了,比如加上快取伺服器,叢集、負載均衡、優化資料庫伺服器等等,以獲取更好的系能。
本文轉自 leizhimin 51CTO部落格,原文連結:http://blog.51cto.com/lavasoft/225828,如需轉載請自行聯絡原作者
相關文章
- 常見效能優化策略總結優化
- CUDA總體優化策略優化
- JDBC總結1JDBC
- webpack優化總結Web優化
- APP優化總結APP優化
- 效能優化總結優化
- JDBC章節總結JDBC
- React 效能優化總結React優化
- SYBASE優化總結(zt)優化
- canvas效能優化總結Canvas優化
- React效能優化總結React優化
- 前端效能優化總結前端優化
- 斜率優化DP總結優化
- iOS 效能優化總結iOS優化
- Oracle SQL優化總結OracleSQL優化
- Oracle SQL優化 總結OracleSQL優化
- 小程式效能優化總結優化
- App瘦身、效能優化總結APP優化
- 優化演算法總結優化演算法
- 系統效能優化總結優化
- 前端效能優化常用總結前端優化
- web前端效能優化總結Web前端優化
- 前端優化實踐總結前端優化
- Android效能優化總結Android優化
- MySQL使用與優化總結MySql優化
- JVM 優化經驗總結JVM優化
- JavaScript 專案優化總結JavaScript優化
- 總結MYSQL的優化薦MySql優化
- webpack 前端構建效能優化策略小結Web前端優化
- 【轉】MySQL 建表的優化策略 小結MySql優化
- 介面優化策略優化
- 策略模式總結模式
- JDBC優化之Batch、FetchJDBC優化BAT
- JDBC批量Insert深度優化JDBC優化
- Android效能優化——效能優化的難題總結Android優化
- 效能優化 - Oracle Tuning 總結 3 優化統計優化Oracle
- 打個總結:Web效能優化Web優化
- ⚠️Flutter 效能優化實踐 總結⚠️Flutter優化