更新同一张表的 JPQL 查询的性能改进

Posted

技术标签:

【中文标题】更新同一张表的 JPQL 查询的性能改进【英文标题】:Performance improvement in JPQL Query for update same table 【发布时间】:2015-04-01 02:22:33 【问题描述】:

我想用 jpql 更新一个表。表结构和条件及查询如下。

-------------------------------------------------------------
ASSIGNMENT | BUSINESS_AREA | DC_CURRENCY | DC_AMOUNT | STATUS
-------------------------------------------------------------

在上面的表结构中,我想将所有行状态更新为已完成 其中 DC_AMOUNT 的总和为零,所有行的 DC_CURRENCY 相同,并且 ASSIGNMENT 也相同

我的方法

    在java层通过查询获取所有赋值号 将我在之前结果集中获得的所有作业编号的状态更新为已完成

查询所有满足条件的赋值号

SELECT 
    q.assignment 
FROM 
    OnAccoutEntity q, OnAccoutEntity r 
WHERE 
    q.assignment = r.assignmet 
    AND q.dcCurrency = r.dcCurrency 
    AND q.businessArea = r.businessArea 
GROUP BY 
    q.assignmnt 
HAVING 
    SUM(q.dcAmount) = 0

UPDATE OnAccoutEntity p
SET p.status = 'COMPETED'
WHERE p.assignment IN ("Result of previous query' )

如果我使用单个查询来更新它会给出异常。

java.sql.SQLException: 您不能在表单子句中指定目标“ONACCCOUNT”进行更新。

请提出更好的方法,因为这很耗时。

【问题讨论】:

将第一个查询用作第二个查询的子查询:where p.assignment in (select q.assignment ...)? 它不起作用,因为它给出了错误“无法指定更新的目标表”请写查询我可能做错了 当某些东西不起作用并且您想知道原因时,请使用相关代码和准确完整的堆栈跟踪来编辑您的问题。 我已经编辑了问题,请告诉我如何解决这个问题 Bad habits to kick : using old-style JOINs - 旧式 逗号分隔的表格列表 样式已替换为 ANSI 中的 proper ANSI JOIN 语法-92 SQL 标准(20 多年前),不鼓励使用它 【参考方案1】:

应该使用EXISTS,

UPDATE
   OnAccoutEntity o
SET
   o.status = 'COMPLETED'
WHERE
   EXISTS (SELECT
              q.assignment
           FROM
              OnAccoutEntity q
           WHERE
              o.assignment = q.assignment
           AND
              q.dcCurrency = o.dcCurrency
           AND
              q.businessArea = r.businessArea
           GROUP BY
              q.assignment
           HAVING SUM(q.dcAmount) = 0)

【讨论】:

这给了异常 ::: java.sql.SQLException: You can't specify target 'ONACCCOUNT' for update in form 子句

以上是关于更新同一张表的 JPQL 查询的性能改进的主要内容,如果未能解决你的问题,请参考以下文章

根据同一张表的结果优化选择表中的所有行?

同一张表的嵌套查询

视图与冗余物理表的查询性能测试

直接查询表和查询返回同一张表的函数的区别

更新同一张表的整列字段

SQL查询显示同一张表的差异