我正在逐字逐句地遵循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。
答案 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 可以直接检索行,而无需扫描剩余的行。