(我的环境: Windows 7 x64和Server 2008,EclipseLink 2.5.2,我已经在JTDS和MS驱动程序以及2008和2012中尝试了以下内容。)
我在一个包含5-5千万行的表中执行分页查询,其中大约500万行符合筛选条件。下面是我用来一次在UI 25行中显示此数据的分页查询。分页工作正常-列表仅包含每页25行。但是,查询需要24秒钟才能返回25行,这似乎很长。
我的目标是记录生成的SQL,这样我就可以确切地看到JPA是如何在SQLServer2008vs 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吗?我认为有两种可能性:
发布于 2014-09-19 15:36:06
尝试将EclipseLink中的日志级别设置为Finest,并检查正在使用的数据库平台。EclipseLink日志记录还将显示发送到数据库的内容。这应该与您从getSQLString()获得的内容相同,但允许您验证您正在执行正确的api,并且初始启动日志记录将显示所使用的平台是否与您的数据库匹配,否则需要使用目标数据库属性:database.htm指定它。
如果plaform支持它,EclipseLink将在生成的http://wiki.eclipse.org/EclipseLink/Examples/JPA/Pagination中使用分页,否则它会使用JDBC来限制发送的结果,然后跳转到返回结果集中的第一个结果,如果分页完全在数据库中完成,效率就会降低。
发布于 2016-05-17 16:44:43
EclipseLink (至少到当前版本2.6.1)既不支持以偏移提取语法形式的Server 2012分页,也不支持较旧的Server顶层语法,请查看EclipseLink数据库支持。相反,EclipseLink在内部使用JDBCFeatureStatement.setMaxRows()
,它实际上丢弃了返回ResultSet
中过多的行。到目前为止,还没有计划在将来的版本中支持这一点。
您可以尝试手动实现此操作,扩展SQLServerPlatform
和重写方法printSQLSelectStatement()
,类似于在PostgreSQLPlatform.printSQLSelectStatement()
中的实现方式。工作原型在这里:https://github.com/roman-sinyakov/eclipselink/blob/master/SQLServer2012Platform.java。
https://stackoverflow.com/questions/25934977
复制相似问题