尝试使用回滚运行 EXPLAIN ANALYZE

Posted

技术标签:

【中文标题】尝试使用回滚运行 EXPLAIN ANALYZE【英文标题】:Trying to run EXPLAIN ANALYZE with rollback 【发布时间】:2018-11-02 19:46:36 【问题描述】:

我正在构建一个 Java 程序,该程序需要在调度 SQL 语句之前自动收集数据。该程序现在运行EXPLAIN 语句并解析结果。

我需要时间参数,所以我需要用ANALYZE运行,但是我不想影响任何数据,所以我需要回滚。当我尝试按照 PostgreSQL 文档中的建议将这一切作为一个块运行时,使用:

BEGIN;
EXPLAIN ANALYZE VERBOSE ...(statement)
ROLLBACK;

我没有得到EXPLAIN 语句的结果,而是我知道这个查询块没有影响任何行。

所以我不确定获取这些数据的最佳方式。我的想法可能是构建一个函数,其中语句是 text 参数,并返回一个只有 1 行/列的表,其中包含 EXPLAIN 输出,但我并不是真正的 PostgreSQL 函数向导,所以更简单的选择是最好的。

不太清楚该怎么做。任何帮助都会有所帮助!

【问题讨论】:

您可能会从语句 解释计划结果中获得 both 更新计数,因此您需要调用 stmt.getMoreResults() 来获得这一切。 请出示使用的代码。 您是否尝试在连接上禁用自动提交,然后仅使用execute() 发送explain... 并使用Connection.rollback() 进行回滚? 其实用的是Greenplum服务器,所以8.2之后fork了。让我看看自动提交设置,我正在使用 java.sql.DriverManager 库,以及带有 .use connection -> connection.prepareStatement(query).also prepareStatement ->preparedStatement.executeQuery().also 的 getConnection 方法 resultSet -> while (resultSet.next()) results.add(resultSet.getString(1)) 编辑您的问题,不要在 cmets 中发布相关信息。 【参考方案1】:

当您说您正在“作为一个块”运行语句时,您可能是指您正在将三个语句运行在一个 java.sql.Statement.execute() 中。

那么你只会看到最后一条语句的结果集,恰好是ROLLBACK

相反,你应该这样做:

conn.setAutocommit(false);
java.sql.Resultset rs = conn.createStatement().executeQuery("EXPLAIN ...");
// retrieve the EXPLAIN result
conn.rollback();

【讨论】:

以上是关于尝试使用回滚运行 EXPLAIN ANALYZE的主要内容,如果未能解决你的问题,请参考以下文章

Postgres EXPLAIN ANALYZE 比正常运行查询快得多

Postgresql 捕获事务错误和回滚

尽管使用了 EXPLAIN 所示的索引,但跨数据库查询需要异常长时间才能运行

MongoDB 索引和投影

mysql explain详解

如何使用实体框架回滚迁移的正确方法