1. 程式人生 > 實用技巧 >十四個高效能Java持久化技巧

十四個高效能Java持久化技巧

>>> hot3.png

介紹

高效能資料訪問層需要大量有關資料庫內部,JDBC,JPA,Hibernate的知識,本文總結了一些可用於優化企業應用程式的最重要技術。

1. SQL語句記錄


如果您使用的是代表您生成語句的框架,則應始終驗證每個語句的有效性和效率。測試時斷言機制甚至更好,因為即使在提交程式碼之前,您也可以捕獲N + 1個查詢問題。

2.連線管理


資料庫連線很昂貴,因此您應始終使用連線池機制。

由於連線數由底層資料庫叢集的功能提供,因此您需要儘快釋放連線。

在效能調優中,您始終必須進行測量,並且設定正確的池大小也沒有區別。即使在將應用程式部署到生產環境中之後,像FlexyPool這樣的工具也可以幫助您找到合適的大小。


3. JDBC批處理


JDBC批處理允許我們在單個數據庫往返中傳送多個SQL語句。在驅動程式和資料庫方面,效能提升都很重要。 PreparedStatements非常適合批處理,一些資料庫系統(例如Oracle)僅支援僅對預準備語句進行批處理。

由於JDBC為批處理定義了一個獨特的API(例如PreparedStatement.addBatch和PreparedStatement.executeBatch),如果您手動生成語句,那麼您應該從一開始就知道是否應該使用批處理。使用Hibernate,您可以使用單個配置切換到批處理。

Hibernate 5.2提供了會話級批處理,因此在這方面更加靈活。

4.語句快取


語句快取是您可以輕鬆利用的最不為人知的效能優化之一。根據底層的JDBC驅動程式,您可以在客戶端(驅動程式)或資料庫端(語法樹甚至執行計劃)快取PreparedStatements。

5. Hibernate識別符號

使用Hibernate時,IDENTITY生成器不是一個好選擇,因為它禁用了JDBC批處理。

TABLE生成器甚至更糟,因為它使用單獨的事務來獲取新識別符號,這會對底層事務日誌以及連線池施加壓力,因為每次我們需要新識別符號時都需要單獨的連線。

SEQUENCE是正確的選擇,甚至SQL Server也支援自2012版本。對於SEQUENCE識別符號,Hibernate長期以來一直提供諸如池化或池化等優化器,這可以減少獲取新實體識別符號值所需的資料庫往返次數。

6.選擇正確的列型別


您應始終在資料庫端使用正確的列型別。列型別越緊湊,資料庫工作集中可以容納的條目越多,索引將更好地適應記憶體。為此,您應該利用特定於資料庫的型別(例如,PostgreSQL中的IPv4地址的inet),特別是因為Hibernate在實現新的自定義型別時非常靈活。

7.關係

Hibernate帶有許多關係對映型別,但並非所有關係對映型別在效率方面都是相同的。

關係

應避免使用單向集合和@ManyToMany列表。如果您確實需要使用實體集合,則首選雙向@OneToMany關聯。對於@ManyToMany關係,使用Set(s),因為它們在這種情況下更有效,或者只是對映連結的多對多表並將@ManyToMany關係轉換為兩個雙向@OneToMany關聯。

但是,與查詢不同,集合的靈活性較低,因為它們不能輕易分頁,這意味著當子關聯的數量相當高時,我們無法使用它們。因此,您應該始終詢問是否真的需要集合。在許多情況下,實體查詢可能是更好的選擇。

8.繼承


在繼承方面,面嚮物件語言和關係資料庫之間的阻抗不匹配變得更加明顯。 JPA提供了SINGLE_TABLE,JOINED和TABLE_PER_CLASS來處理繼承對映,並且這些策略中的每一個都有優點和缺點。

SINGLE_TABLE在SQL語句方面表現最好,但由於我們不能使用NOT NULL約束,因此我們在資料完整性方面失敗了。

JOINED解決了資料完整性限制,同時提供了更復雜的語句。只要您不對基型別使用多型查詢或@OneToMany關聯,此策略就可以了。它的真正力量來自於資料訪問層一側的策略模式支援的多型@ManyToOne關聯。

應避免使用TABLE_PER_CLASS,因為它不會生成有效的SQL語句。

9.永續性上下文大小


使用JPA和Hibernate時,應始終注意持久化上下文大小。出於這個原因,你絕不應該使用大量的託管實體來臃腫它。通過限制託管實體的數量,我們獲得了更好的記憶體管理,並且預設的髒檢查機制也將更加高效。

10.只獲取必要的東西


獲取過多資料可能是資料訪問層效能問題的首要原因。一個問題是實體查詢是專門使用的,即使對於只讀投影也是如此。

DTO投影更適合於獲取自定義檢視,而實體應僅在業務流程需要修改它們時獲取。

EAGER提取是最糟糕的,你應該避免反模式,如Open-Session in View。

11.快取


快取圖層

關係資料庫系統使用許多記憶體緩衝區結構來避免磁碟訪問。資料庫快取經常被忽視。我們可以通過適當調整資料庫引擎來顯著縮短響應時間,以便工作集駐留在記憶體中,並且不會一直從磁碟中獲取。

對於許多企業應用程式,應用程式級快取不是可選的。應用程式級快取可以縮短響應時間,同時在資料庫因維護而關閉或由於某些嚴重的系統故障而提供只讀輔助儲存。

二級快取對於減少讀寫事務響應時間非常有用,尤其是在主從複製體系結構中。根據應用程式的要求,Hibernate允許您在READ_ONLY,NONSTRICT_READ_WRITE,READ_WRITE和TRANSACTIONAL之間進行選擇。

13.釋放資料庫查詢功能


僅僅因為您使用JPA或Hibernate,並不意味著您不應該使用本機查詢。您應該利用視窗函式,CTE(公用表表達式),CONNECT BY,PIVOT。

這些構造允許您避免獲取太多資料,以便稍後在應用程式層中對其進行轉換。如果您可以讓資料庫進行處理,則可以僅獲取最終結果,從而節省大量磁碟I / O和網路開銷。為避免主節點過載,您可以使用資料庫複製並使多個Slave節點可用,以便在Slave上而不是在Master上執行資料密集型任務。

14.向上擴充套件和向外擴充套件

關係資料庫的確可以很好地擴充套件。如果Facebook,Twitter,Pinterest或StackOverflow可以擴充套件其資料庫系統,則很有可能將企業應用程式擴充套件到其特定的業務需求。

資料庫複製和分片是提高吞吐量的非常好的方法,您應該完全利用這些經過實戰考驗的體系結構模式來擴充套件您的企業應用程式。

結論

高效能資料訪問層必須與底層資料庫系統產生共鳴。 瞭解關係資料庫的內部工作原理以及正在使用的資料訪問框架可以使高效能企業應用程式與幾乎無法爬行的應用程式之間產生差異。

您可以採取許多措施來改善資料訪問層的效能,我只是在這裡贅述。
如果您想要閱讀有關此特定主題的更多資訊,您還應該檢視我的高效能Java永續性書籍。 這本書有450多頁,非常詳細地解釋了所有這些概念。

注:文中涉及的連結不再補充。

轉載於:https://my.oschina.net/boonya/blog/3013125