重用 Postgres 准备好的语句

Reusing Postgres prepared statement

我在看这个问题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

Prepared statements only last for the duration of the current database session. When the session ends, the prepared statement is forgotten

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

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

是生成单个计划还是生成多个计划至少取决于以下几点(生成计划的是PREPARE STATEMENT):

A prepared statement can be executed with either a generic plan or a custom plan. A generic plan is the same across all executions, while a custom plan is generated for a specific execution using the parameter values given in that call. Use of a generic plan avoids planning overhead, but in some situations a custom plan will be much more efficient to execute because the planner can make use of knowledge of the parameter values. (Of course, if the prepared statement has no parameters, then this is moot and a generic plan is always used.)

By default (that is, when plan_cache_mode is set to auto), the server will automatically choose whether to use a generic or custom plan for a prepared statement that has parameters. The current rule for this is that the first five executions are done with custom plans and the average estimated cost of those plans is calculated. Then a generic plan is created and its estimated cost is compared to the average custom-plan cost. Subsequent executions use the generic plan if its cost is not so much higher than the average custom-plan cost as to make repeated replanning seem preferable.

[引用 Postgres SQL PREPARE 命令]