2014-09-19 61 views
0

(我的環境:Windows 7 x64和Server 2008,EclipseLink 2.5.2,我已經嘗試了下面的JTDS和MS JDBC驅動程序,以及MS SQL Server Express 2008和2012 )EclipseLink生成的SQL不包含分頁

我正在做一個分頁查詢的表格,其中有五千五百萬行的任何地方,大約有五百萬行符合過濾條件。以下是我用來在UI 25行中一次顯示此數據的分頁查詢。分頁工作正常 - 列表中每個頁面只包含25行。但是,查詢需要24秒才能返回25行,這似乎很長。

我的目標是記錄生成的SQL,以便我可以準確瞭解JPA如何在SQL Server 2008 vs 2012中完成分頁。但生成的SQL不包含與分頁有關的任何內容,這讓我想知道否則我沒有在生成的SQL中看到。

查詢:

CriteriaBuilder cb = JPA.em().getCriteriaBuilder(); 
CriteriaQuery<RGHICarrierPull> cq = cb.createQuery(RGHICarrierPull.class); 
Root<RGHICarrierPull> from = cq.from(RGHICarrierPull.class); 
CriteriaQuery<RGHICarrierPull> select = cq.select(from); 
// Add filter/sort predicates to "predicates" 
... 
select.where(predicates); 
// Apply pagination 
records.setFirstResult((page-1)*limit); 
records.setMaxResults(limit); 
// Get data 
List<RGHICarrierPull> lst = records.getResultList(); 

要登錄編程生成的SQL:

// Log the sql for this query 
Session session = JPA.em().unwrap(JpaEntityManager.class).getActiveSession(); 
DatabaseQuery databaseQuery = ((EJBQueryImpl)records).getDatabaseQuery(); 
databaseQuery.prepareCall(session, new DatabaseRecord()); 
System.out.println(databaseQuery.getSQLString()); 

記錄的SQL:

SELECT t1.SHIPTO_ZIP, t1.WHSE, t1.ANYNBR1, t1.ANYTEXT1, t1.CREATE_DATE_TIME, t1. 
MOD_DATE_TIME, t1.PULL_TIME, t1.PULL_TIME_AMPM, t1.PULL_TRLR_CODE, t1.USER_ID, 
1.SHIP_VIA FROM Ship_Via t0, RGHI_Carrier_Pull t1 WHERE ((t1.WHSE = 'WHSE1') AND 
(t0.SHIP_VIA = t1.SHIP_VIA)) ORDER BY t0.SHIP_VIA ASC, t1.SHIPTO_ZIP ASC 

很顯然,這不是一個分頁查詢,因此,如果我直接運行這個查詢,它運行了一分多鐘並返回所有500萬行。如果我使用persistence.xml設置來記錄所有JPA查詢,並且如果我從MS SQL Server登錄SQL,則會得到相同的結果。

這是實際生成的SQL嗎?我看到兩種可能性:

  • 這是完全生成的SQL,但EclipseLink正在做其他事情來完成分頁。
  • 的EclipseLink正在記錄此生成的SQL被添加到它之前的分頁東西

回答

0

嘗試設置中的EclipseLink到最優秀的日誌級別,並檢查正在使用的數據庫平臺。 EclipseLink日誌記錄還將顯示發送到數據庫的內容。這應該記錄與你從getSQLString()得到的相同的SQL,但允許你驗證你正在執行正確的api,並且最初的啓動日誌會顯示正在使用的平臺是否與你的數據庫匹配,否則它將需要使用目標數據庫特性來指定:http://www.eclipse.org/eclipselink/documentation/2.4/jpa/extensions/p_target_database.htm

的EclipseLink將如這裏所述http://wiki.eclipse.org/EclipseLink/Examples/JPA/Pagination如果者平臺支持它使用分頁生成的SQL內,否則將求助於使用JDBC API限制橫跨發送的結果,然後跳到返回結果集中的第一個結果,如果分頁完全在數據庫中完成,效率會降低。

0

EclipseLink(至少到當前版本2.6.1)既不支持OFFSET-FETCH語法形式的SQL Server 2012分頁,也不支持舊版SQL Server TOP語法,請查看EclipseLink Database Support。相反,EclipseLink內部使用JDBC功能Statement.setMaxRows(),它基本上會丟棄返回的ResultSet中的過多行。到目前爲止,還沒有計劃在未來的版本中支持這一點。

您可以嘗試執行此操作,以手動方式擴展SQLServerPlatform和覆蓋方法printSQLSelectStatement(),與PostgreSQLPlatform.printSQLSelectStatement()中的方法類似。工作原型在這裏:https://github.com/roman-sinyakov/eclipselink/blob/master/SQLServer2012Platform.java