为什么我的JDBC游标执行速度如此之慢?

时间:2011-08-10 05:48:17

标签: postgresql jdbc database-cursor

我正在逐字逐句地遵循this page(例5.2)中列出的代码。

我的查询非常简单

  

SELECT * FROM“LSERAW”WHERE“DATETIME”> ='Sat Jan 01 00:00:00 EST 2011'和“DATETIME”< ='Thu Jun 30 00:00:00 EST 2011'ORDER BY“ DATETIME“LIMIT 10000000

数据库在DATETIME上编入索引。但是,当我将LIMIT从1000万增加到1亿时,我的代码需要很长时间才能进入while循环。 1000万这是非常快的。我认为使用游标while循环应该始终及时开始。我的代码出了什么问题吗?

底层数据库是Windows上的PostgreSQL。

2 个答案:

答案 0 :(得分:1)

您的JDBC连接自动提交设置为true。驱动程序首先将整个结果集加载到RAM中。

将自动提交更改为false,它会更快地返回。

答案 1 :(得分:0)

ORIGINAL ATTEMPT(可能不对,请参阅下面的编辑):我不是游标专家,但我很确定使用游标并不意味着SELECT语句会返回正确远。服务器仍然必须像任何其他查询一样执行它,这可能需要时间。我建议尝试找出系统的哪个部分正在阻止。

Java程序“挂起”后,使用单独的数据库客户端(例如psql)运行SELECT * FROM pg_stat_activity。如果您在列表中看到您的查询,则表示服务器仍在处理它。

您也可以将PostgreSQL服务器的log_min_duration_statement更改为(作为示例)1000。然后,在重新启动PostgreSQL(或使用pg_ctl reload或类似的东西)后,再次运行该程序。查询完成后,您应该在PostgreSQL日志文件中看到一行表明它花了多长时间。

祝你好运!


编辑:我发现this blog entry描述了类似的问题。

  

[查询]花了几秒钟才回来,因此创建了一个否定的   用户的初步体验。从那以后我学到了什么   我只需要应用一些环境设置。

     

他们是:

set enable_sort = off
set enable_seqscan = off
  

你可以看看这些。他们只是阻止PostgreSQL尝试   如果有任何索引,请执行filesort或filemerge或顺序扫描   当下。现在,在光标之外,您仍然会获得重要的信息   延迟,因为所有行都将被传递。必须有一个   用于分页的客户端方法,否则服务器不会   能够以块的形式传递数据。 Capice?

     

但是在游标中,上面的效果非常好。几乎   瞬时的。

我实际上没有任何表格存在1亿行,所以我无法测试。但你可能想尝试一下。


编辑2: Section 11.4 of the PostgreSQL manual解释了为什么enable_sort特别重要:

  

一个重要的特例是ORDER BY与LIMIT n:结合使用   显式排序必须处理所有数据以识别第一个   n行,但如果有一个与ORDER BY匹配的索引,则为第一个n   可以直接检索行,而无需扫描剩余的行。