Java 与在pgadmin中执行查询相比,使用JDBC执行Postgresql查询需要更多的时间

Java 与在pgadmin中执行查询相比,使用JDBC执行Postgresql查询需要更多的时间,java,postgresql,jdbc,Java,Postgresql,Jdbc,我有一个存储过程,带有一个参数 让我们称之为x 当我跑步时 select * from x('myParameter') 它在4分钟内完成 现在,我尝试在java中执行相同的存储过程,如下所示:- PreparedStatement statement = connection.prepareStatement("Select * from x('myParameter')"); org.postgresql.PGStatement pgstmt = (org.postgresql.PGSta

我有一个存储过程,带有一个参数

让我们称之为
x

当我跑步时

select * from x('myParameter')
它在4分钟内完成

现在,我尝试在java中执行相同的存储过程,如下所示:-

PreparedStatement statement = connection.prepareStatement("Select * from x('myParameter')");
org.postgresql.PGStatement pgstmt = (org.postgresql.PGStatement)statement;
pgstmt.setPrepareThreshold(1);
boolean usingServerPrepare = pgstmt.isUseServerPrepare();
System.out.println(usingServerPrepare);
statement.execute();
这大约需要26小时才能完成

我最初尝试时没有使用
pgstmt.setPrepareThreshold(1),,
i、 e.prepareThreshold的默认值。
结果是一样的

然后,我尝试使用“set enable_nestloop false”作为存储过程的第一行的java程序,它在4分钟内完成

当我显式地强制执行服务器端准备的语句时,我无法理解为什么查询会更改执行计划

我正在使用Postgres9.4和Java8。我还使用PGBouncer进行连接池


我的问题是——为什么JDBC会影响执行计划呢?有没有办法强制服务器端执行计划执行由java程序触发的查询?

得到解决方案:- 存储过程中使用了一个表,如“tab1”。

当我们从PGAdmin/SQL运行存储过程时,几个小时前已经创建/修改了tab1窗口

在自动运行中,使用java,tab1在存储过程执行前几秒钟创建和加载/修改。
在第一种情况下(从PGAdmin/SQL窗口运行存储过程),我们在PGAdmin中运行存储过程时,tab1上的自动分析已经完成,而在第二种情况下(使用java自动运行),tab1上的自动分析尚未启动或正在处理中,因为tab1刚刚被修改。
这使得Postgres在从PGAdmin运行查询时选择了比使用java运行时更好的计划


摘要-选择了不同的计划,因为在第二种情况下,在运行存储过程时,自动分析未完成,导致查询计划选择不佳。

它返回多少行?那么函数
x
到底是做什么的呢?请您的问题添加有关表(包括所有索引)的
create table
语句和函数
x
的代码。请发短信,它不返回任何内容。它是一个存储过程,执行一些连接并将数据加载到另一个表中。从存储过程执行查询和使用JDBC执行查询时的条件相同。您确定在同一数据库上执行查询吗?是的,我确定它在同一数据库上。我可以在服务器状态和表pg_stat_activity中看到它。这两种情况下的查询都是相同的。安装后,将其添加到
session\u preload\u libraries
,在
postgresql.conf
中设置
auto\u explain.log\u min\u duration=0
auto\u explain.log\u nested\u statements=on
,然后重新加载数据库服务器。然后从
psql
和Java程序调用该函数,并比较在PostgreSQL日志中找到的执行计划。这些信息将有助于了解发生了什么。