2014-09-19 62 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