JPA 2.1 / EclipseLink 2.5.2中是否存在查询集合参数的最大大小(如果重要的话,连接到mysql 5.6)?
例如,以下代码中ids
的最大允许和/或建议大小是多少,以确保性能并避免JPA / EclipseLink / mysql中的任何可能的错误或问题?:
@PersistenceContext
private EntityManager em;
{
final Collection<Long> ids = /*obtain a Collection of IDs*/;
em.createQuery("select e from Entity1 e where e.id in :ids")
.setParameter("ids", ids);
}
答案 0 :(得分:4)
您的问题没有简单明了的答案,因为它取决于多种因素,如JVM的进程堆大小,持久性提供程序专有功能,底层数据库调优选项等。在现实生活中所有这些因素应该相当单独调整。
MySQL 5.6参考手册,章节 12.3.2比较函数和操作符定义:
IN 列表中的值数量仅受限于 max_allowed_packet值。
由于max_allowed_packet等于一个数据包或任何生成/中间字符串的最大大小(此处:1GB),理论上应该允许发送最大大小为1GB的查询字符串。
JPA 2.0规范(JSR-317),章节 4.6.9在Experssions 中没有提到任何有关限制的内容,所以至少我们可以假设它是&#39是最弱的&#34;工具链中的组件(应用程序容器,持久性提供程序,底层数据库,JVM堆大小)。
正如@Chris所注意到的,Oracle在每个语句中限制为1000个参数。 James上的blog(TopLink / EclipseLink的前架构师)描述了与EclipseLink类似的问题:
我在这次运行中注意到的第一件事是Oracle有一个限制 每个语句1,000个参数。由于IN批量提取绑定了一个 大阵列,我读了5,000个对象,超出了这个限制 并且运行因数据库错误而爆炸。 中的 BatchFetchPolicy EclipseLink说明了这一点,定义了最大数量的大小 ID包含IN 。 EclipseLink中的默认大小限制是 假设是500(...)
和
EclipseLink定义了 JPA查询提示&#34; eclipselink.batch.size&#34; 允许设置大小。因此我将此设置为500以进行测试。 这意味着要读入所有5,000个对象,IN批处理 fetch将需要每批获取的关系执行10个查询。
无论如何,我鼓励阅读整篇文章。
答案 1 :(得分:0)
&#34;限制&#34;是SQL中数据库中的限制。查看JPA提供程序创建的SQL,然后查看您使用的RDBMS中该语法的限制
答案 2 :(得分:0)
使用setMaxResults()
方法。
例如结果如下
1,2,3,4,5,6,7,8,9,10
仅最大结果
em.createQuery(...).setParameter(...).setMaxResults(5).getResultList();
输出
1,2,3,4,5
使用范围
em.createQuery(...).setParameter(...).setFirstResult(3).setMaxResults(5).getResultList();
输出
4,5,6,7,8
答案 3 :(得分:0)
其他框架(如openJPA)能够为用户透明地拆分SQL,因此如果带有占位符的IN子句支持超过1000个项目的列表,则会自动拆分。 如果EclipseLink也支持这样的功能会很好,因为它可以通过实现自动化。根据底层数据库将工作负载转移给用户,对开发人员不友好。