首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >EclipseLink生成的SQL不包括分页

EclipseLink生成的SQL不包括分页
EN

Stack Overflow用户
提问于 2014-09-19 13:21:16
回答 2查看 1.3K关注 0票数 2

(我的环境: 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中还有什么是我看不到的。

查询:

代码语言:javascript
运行
复制
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:

代码语言:javascript
运行
复制
// 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:

代码语言:javascript
运行
复制
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,但是EclipseLink正在做其他的事情来完成分页。
  • EclipseLink正在记录此生成的SQL,然后再添加分页内容。
EN

回答 2

Stack Overflow用户

发布于 2014-09-19 15:36:06

尝试将EclipseLink中的日志级别设置为Finest,并检查正在使用的数据库平台。EclipseLink日志记录还将显示发送到数据库的内容。这应该与您从getSQLString()获得的内容相同,但允许您验证您正在执行正确的api,并且初始启动日志记录将显示所使用的平台是否与您的数据库匹配,否则需要使用目标数据库属性:database.htm指定它。

如果plaform支持它,EclipseLink将在生成的http://wiki.eclipse.org/EclipseLink/Examples/JPA/Pagination中使用分页,否则它会使用JDBC来限制发送的结果,然后跳转到返回结果集中的第一个结果,如果分页完全在数据库中完成,效率就会降低。

票数 0
EN

Stack Overflow用户

发布于 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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25934977

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档