2010-03-11 49 views
0

我使用JBoss的EJB 3.0實現(JBoss的4.2.3服務器) 一開始,我創建的本機查詢使用建設所有的時間像如何緩存在EJB和返回結果效率(性能POV)

Query query = entityManager.createNativeQuery("select * from _table_"); 
查詢

雖然效率不高,但我進行了一些測試,發現它確實需要很多時間...然後我找到了一個更好的方法來處理它,使用註釋來定義原生查詢:

@NamedNativeQuery(name = "fetchData", value = "select * from _table_", resultClass=Entity.class) 

然後就用它

Query query = entityManager.createNamedQuery("fetchData"); 

上面的代碼行的性能比,我從開始更好的兩倍,但還是不如我想象的那麼好......後來我發現,我可以切換到休眠標註爲NamedNativeQuery(反正,JBoss的實現EJB是基於Hibernate),並加入一兩件事:

@NamedNativeQuery(name = "fetchData2", value = "select * from _table_", resultClass=Entity.class, readOnly=true) 

readOnly - 標記的結果是否在只讀模式或不取。這聽起來不錯,因爲至少在我的這種情況下,我不需要更新數據,我只是想獲取報告。當我開始服務器測量性能時,我注意到沒有readOnly = true的查詢(默認情況下它是false)返回每次迭代的結果越來越好,同時另一個(fetchData2)的工作方式類似於「穩定」並且具有時間差異他們之間越來越短,經過雙方的5次迭代的速度幾乎是一樣的...

的問題是:

1)是否有任何其他方式使用最多加快查詢?似乎命名查詢應該準備一次,但我不能說...事實上,如果要創建查詢一次,然後只是使用它,從性能的角度來看會更好,但是緩存這個對象是有問題的,因爲在創建查詢後,我可以設置參數(當我在查詢中使用「:variable」時),並且它改變了查詢對象(不是嗎?)。那麼,在這裏有什麼方法來緩存它們?或者命名查詢是我可以使用的最佳選擇?

2)任何其他方法如何使結果更快地讀取。我的意思是,例如我不需要這些實體被連接,我不會更新它們,我需要的只是獲取數據集合。也許readOnly是唯一可用的方式,所以我不能加快速度,但誰知道:)

P.S.我沒有詢問數據庫性能,現在我需要的是如何不一直創建查詢對象,所以請高效使用它,並且「允許」EJB以較少的工作完成與返回數據相同的結果。

添加15.03.2010:
通過查詢我的意思是查詢對象(所以如何緩存此對象重用);並且緩存查詢結果對我來說不是一個解決方案,因爲查詢中的原因對於每個查詢而言可能幾乎是唯一的,因爲其中存在浮點指向參數。 Cache不會理解「a> 50.0001」和「a> 50.00101」可以給出相同的結果,但也不能。

回答

0

您可以使用second level cachequery cache來避免碰到數據庫(對於只讀對象來說工作得特別好)。 Hibernate支持二級緩存(使用第三方緩存提供程序),但它是JPA 1.0的擴展。

+0

謝謝你的回覆。 在許多情況下,我無法避免碰到數據庫,因爲我在表中有mlns的數據,而且我獲取的內容取決於輸入參數,並且由於浮點輸入數據在大多數情況下使用where子句中的參數進行選擇將是唯一的。它沒有足夠的內存來緩存它......這就是爲什麼我儘可能優化EJB/Hibernate代碼(查詢創建;數據轉換......) – Maxym 2010-03-14 16:57:57

+0

以及可以緩存的內容我以自己的方式完成了它,所以二級緩存可以是我的緩存策略的另一種選擇...謝謝! – Maxym 2010-03-14 17:00:18

+0

@Maxym *「使用where子句中的參數選擇將是唯一的」*啊,我明白了,實際上,查詢緩存將不是一個解決方案。但這個問題並不明顯。也許你應該提到這一點。 – 2010-03-14 17:23:00