的EclipseLink生成的SQL不包括分页(EclipseLink generated SQL

2019-10-21 00:05发布

(我的环境:Windows 7 x64和Server 2008中,的EclipseLink 2.5.2,我已经试过JTDS和MS JDBC驱动程序下面,并与MS SQL Server Express的2008年和2012年)

我做在5-50万行的任何地方表中的分页查询,有大约500万行符合过滤条件。 以下是我使用的同时,以在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服务器的SQL。

这是实际生成的SQL? 我看到两种可能性:

  • 这是一个完整生成的SQL,但在的EclipseLink做别的事情来实现分页。
  • 的EclipseLink正在记录此生成的SQL被添加到它之前的分页东西

Answer 1:

尝试设置中的EclipseLink到最优秀的日志级别,并检查正在使用的数据库平台。 的EclipseLink记录还将展示什么是发送到数据库。 这应该记录相同的SQL,你从getSQLString()得到了什么,而是让你来验证你正在执行正确的API,以及初始启动日志记录将显示,如果正在使用的平台相匹配的数据库,否则将需要使用目标数据库属性来指定: http://www.eclipse.org/eclipselink/documentation/2.4/jpa/extensions/p_target_database.htm

的EclipseLink将这里描述使用分页生成的SQL内http://wiki.eclipse.org/EclipseLink/Examples/JPA/Pagination若者平台支持它,否则将求助于使用JDBC API来限制发送的订单结果,然后跳转到第一个结果在返回的结果集,这是效率较低那么如果分页在数据库完全完成。



Answer 2:

的EclipseLink(至少到当前版本2.6.1)支持偏移取语法也较旧的SQL Server的TOP语法,检查出的形式既不是SQL Server 2012的分页EclipseLink的数据库支持 。 代替的EclipseLink内部使用JDBC特征Statement.setMaxRows()基本上从返回丢弃过度行ResultSet 。 而且也没有计划支持,在未来的版本为止。

你可以尝试实现这个手动延长SQLServerPlatform和压倒一切的方法printSQLSelectStatement()类似,它是如何在做PostgreSQLPlatform.printSQLSelectStatement() 该工作原型是在这里: https://github.com/roman-sinyakov/eclipselink/blob/master/SQLServer2012Platform.java 。



文章来源: EclipseLink generated SQL doesn't include pagination