【问题标题】:How to improve postgresql request that throw a "statement timeout"如何改进引发“语句超时”的 postgresql 请求
【发布时间】:2013-05-01 12:24:50
【问题描述】:

此请求使用 postgresql 引发语句超时。

DELETE FROM my_table where my_table.id IN (
   SELECT DISTINCT b.id 
   FROM my_table a
   LEFT JOIN my_table b
   on b.rowA = a.rowA and b.rowB = true
   WHERE a.rowB = false
)

由于某些原因,我无法在 postgresql 上增加我的超时时间。所以,我需要改进我的要求。如何改进它?也许不使用IN?该怎么做?

感谢您的帮助。


编辑更多信息:

我在一个 JAVA 批处理中,我收到的错误消息如下:

原因:org.postgresql.util.PSQLException: ERROR: canceling 由于语句超时而导致的语句 org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1525) 在 org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1309) 在 org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:188) 在 org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:452) 在 org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:354) 在 org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:308) 在 org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:102)

【问题讨论】:

  • 什么进程导致超时?你得到什么错误信息?你只想停止超时吗?如果您想让 DELETE 运行得更快,我们将需要更多信息。例如,关于表的一些信息,例如删除了多少行、需要多长时间、解释计划和实际查询。
  • @jonearles 请查看我的编辑了解更多详情。是的,我只想停止超时,当我的表中没有太多行时,请求有效。删除的数量或行数取决于表格内容(有时为数十万,有时为 0)。这个查询是真正的查询,我的表名不会给你更多信息。
  • 我根据您的编辑重新标记了问题。您可能还想更新问题和标题。我认为您的问题与 PL/SQL 无关。

标签: java performance postgresql timeout plpgsql


【解决方案1】:

我会删除 distinct 和 left join。

delete from my_table where my_table.id in (select b.id from tblA a, tblB b 
where a.rowB = false and b.rowa = a.rowa and b.rowb = true);

问题的主要原因是左连接。为什么要在表 a 上使用左连接并将结果基于表 b 的 id?如果您会使用表 a 的 id,那么这是否有意义。从表 a 的角度来看,左连接将返回表 a 中的所有 id,即使表 b 中没有匹配项也是如此。这不是您想要的,因为它可能是大量数据。您需要表 a 和表 b 的子集。因此,您不应该在不使用它的情况下询问(左连接)中的所有数据。 Distinct 也会产生性能问题。只有当它具有附加值时才使用它。我在这里看不到附加值。

【讨论】:

  • 感谢您的回答,让我看到我不需要 LEFT JOIN 而是 INNER JOIN。我保留了我的 DISTINCT,并将我的请求减少了 10000 个值的一部分。我这样做是因为问题不在于执行联合的时间,而在于删除的时间。
  • 很高兴知道它有帮助。事实上,INNER JOIN 相当于我写的 where 子句。随着从 Oracle 9i 到 10i 的变化,distinct 关键字出现了不同的解释。它在性能上有很大的不同。从那时起,我尽可能避免它。您使用 distinct 的方式是明确的,并且在任何 SQL 方言中都能很好地执行。只是我的 2 美分。
【解决方案2】:

您不能在 SQL 上下文中使用 truefalse(即布尔文字),即使是使用 PL/SQL。

【讨论】:

  • 如果它可以编译,那么在其他未显示的代码中,您有名为 true 和 false 的局部变量。这样做是一种糟糕的做法。
  • 好的,感谢您提供的信息。无论如何,这不是我的问题的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-26
  • 1970-01-01
  • 2022-10-07
  • 1970-01-01
相关资源
最近更新 更多