重用Postgres准备好的语句

问题描述 投票:1回答:1

我正在看这个问题Reusing a PreparedStatement multiple times

假设我有两个版本的代码。每次使用后,第一个按钮都会在PreparedStatement循环内关闭for

connection.autoCommit(false)    
for (int i=0; i<1000; i++) {
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setObject(1, someValue);
        preparedStatement.executeQuery();
        preparedStatement.close();    // 🡄 Close after each use.
    }
    connection.commit();
    connection.close();

在第二个示例中,PreparedStatement保持打开状态以供重复使用,然后在for循环之后将其关闭。

connection.autoCommit(false)
PreparedStatement preparedStatement = connection.prepareStatement(sql);
for (int i=0; i<1000; i++) {
    preparedStatement.clearParameters();
    preparedStatement.setObject(1, someValue);
    preparedStatement.executeQuery();
}
preparedStatement.close();           // 🡄 Close after repeated uses.
connection.commit();
connection.close();

您可以看到我确实在循环中创建和关闭PS或重复使用相同的PS。我确实使用postgres并根据documentation

准备好的语句仅在当前数据库会话期间持续。会话结束时,准备好的语句将被忘记]

据我了解,如果我使用postgres,则以上两个示例将以相同的方式处理,因为它是在同一事务中执行的。因此,例如在第一个在循环内具有new语句的代码示例中,postgres将为该语句创建单个计划程序,即使我们在循环中关闭语句并创建新语句,postgres也会重复使用缓存的语句,因为它发生在同一会话(事务)中,仅当提交事务(connection.commit())时,才会删除此缓存的计划程序。我对吗 ?

java postgresql jdbc prepared-statement
1个回答
2
投票

[准备好的语句持续时间将持续到数据库会话的持续时间,该持续时间与事务不同(会话在客户端断开连接时结束,而事务通常通过COMMIT或ROLLBACK结束)。

是否生成单个计划或多个计划至少取决于以下内容(生成计划的是PREPARE STATEMENT:]

通用计划在所有执行中都是相同的,而自定义计划使用给定的参数值为特定执行生成在那个电话里。使用通用计划可以避免计划开销,但是在某些情况下,自定义计划的执行效率将大大提高因为计划者可以利用参数值的知识。(当然,如果准备好的语句没有参数,那么这是辩论,并始终使用通用计划。)

默认情况下(即,当plan_cache_mode设置为auto时,服务器会自动选择将通用计划还是自定义计划用于具有参数的准备好的语句。当前的规则是前五个执行是通过自定义计划完成的,计算出这些计划的平均估计成本。然后是通用创建计划,并将其估计成本与平均值进行比较定制计划成本。如果后续计划使用通用计划,则后续执行成本不高于平均定制计划成本,使重复的计划似乎更可取。

© www.soinside.com 2019 - 2024. All rights reserved.