我有一个与PostgreSQL DB的连接(使用PostgreSQL JDBC驱动程序(,我设置了网络超时(使用setNetworkTimeout
方法(,它有一些奇怪的东西。
当我将连接用于简单的查询(如 select * from table
(时,这需要花费大量时间,它工作正常(等待查询返回结果(。但是当我将连接用于使用函数(如 select max(a) from table
(的查询时,这也需要花费大量时间,由于超时,它会引发异常。
示例代码:
// Queries which takes more than 5 seconds
String bigQuery = "select * from data.bigtable tb1 inner join data.bigtable tb2 on tb1.a like '%a%'";
String bigQueryWithFunction = "select max(tb1.a) from data.bigtable tb1 inner join data.bigtable tb2 on tb1.a like '%a%'";
// Creating a connection with 5 seconds network timeout
Connection con = source.getConnection();
con.setNetworkTimeout(Executors.newSingleThreadExecutor(), 5000);
con.setAutoCommit(false);
Statement st2 = con.createStatement();
st2.execute(bigQueryWithFunction); // This line DOES throws an exception
st2.execute(bigQuery); // This line DOES NOT throws an exception
(忽略查询的逻辑。
有人可以向我解释为什么会发生这种情况吗?
PostgresSQL会在结果行可用时立即将其流式传输到客户端。
在第一个查询中,将很快返回第一个结果行,即使查询需要很长时间才能完成。JDBC 驱动程序收集结果并等待查询完成,但网络连接不会再空闲
。第二个查询完成所需的时间与第一个查询的时间差不多,但在计算连接中的所有结果行之前,它无法返回其第一个(也是唯一的(结果行。因此,网络连接上的空闲时间很长,这会导致超时。