OpenJpa 中具有大列表的 IN 子句导致语句过于复杂
Posted
技术标签:
【中文标题】OpenJpa 中具有大列表的 IN 子句导致语句过于复杂【英文标题】:IN clause with large list in OpenJpa causing too complex statement 【发布时间】:2014-10-06 06:51:32 【问题描述】:我必须创建一个命名查询,我需要按一些字段对结果进行分组,并且还使用 IN 子句来限制我的结果。
它看起来像这样
SELECT new MyDTO(e.objID) FROM Entity e WHERE e.objId IN (:listOfIDs) GROUP BY e.attr1, e.attr2
我正在使用 OpenJPA 和 IBM DB2。在某些情况下,我的 ID 列表可能非常大(>80.000 个 ID),然后生成的 SQL 语句对于 DB2 来说变得过于复杂,因为最终生成的语句会打印出所有 ID,如下所示:
SELECT new MyDTO(e.objID) FROM Entity e WHERE e.objId IN (1,2,3,4,5,6,7,...) GROUP BY e.attr1, e.attr2
有什么好的方法来处理这种查询吗?一种可能的解决方法是将 ID 写入临时表中,然后在该表上使用 IN 子句。
【问题讨论】:
JPA 确实是为“少数”记录(仍然可能很多)而设计的,而且集合大小不是。你在做什么,你一次弄乱了这么多记录?您最好将批量加载到要加入的表中(类似于现有答案,但有专门的工具)。 【参考方案1】:您应该将所有值放在一个表中,并将查询重写为连接。这不仅可以解决您的查询问题,还应该更加高效。
declare global temporary table ids (
objId int
) with replace on commit preserve rows;
--If this statement is too long, use a couple of insert statements.
insert into session.ids values
(1,2,3,4,....);
select new mydto(e.objID)
from entity e
join session.ids i on
e.objId = i.objId
group by e.attr1, e.attr2;
【讨论】:
这可以工作,但我如何访问我的 JPQL 语句中的临时表?我无法直接访问“会话”,因为它未被识别为实体。 所以这似乎是最好的解决方案。我不能使用全局临时表,但我的方法有效。我正在使用“普通”表并根据需要用 id 列表填充它。以上是关于OpenJpa 中具有大列表的 IN 子句导致语句过于复杂的主要内容,如果未能解决你的问题,请参考以下文章
OpenJPA/MySQL:在 where 子句中使用同一张表时修改表
我可以使用Java代码在sql语句(Oracle)的IN子句中传递字符串列表吗