我正在使用libdbi连接到大型postgresql数据库(3亿条记录)并执行SELECT *
查询,然后逐行显示结果。我正在获得完全交换和内存,所以看起来autocommit
已启用并且它将整个结果集加载到内存中。是否有任何选项可以禁用自动提交或至少在java中提交像ResultSet.HOLD_CURSORS_OVER_COMMIT
之后保留游标?我没有找到dbi_conn_set_option
的任何选项。这是我的代码:
dbi_conn conn;
dbi_result result;
int64_t id;
dbi_initialize(NULL);
conn = dbi_conn_new("pgsql");
if (conn == NULL)
{
printf("connection error.\n");
return EXIT_FAILURE;
}
dbi_conn_set_option(conn, "host", "127.0.0.1");
dbi_conn_set_option(conn, "username", "postgres");
dbi_conn_set_option(conn, "password", "123456");
dbi_conn_set_option(conn, "dbname", "backup");
if (dbi_conn_connect(conn) < 0)
{
printf("could not connect to database.\n");
return EXIT_FAILURE;
}
result = dbi_conn_query(conn, "SELECT * FROM tbl");
if (result)
{
while (dbi_result_next_row(result))
{
id = dbi_result_get_longlong(result, "_id");
printf("This is _id: %ld\n", id);
}
dbi_result_free(result);
}
dbi_conn_close(conn);
dbi_shutdown();
答案 0 :(得分:1)
它与autocommit无关。
内存不足问题的解决方案确实是使用游标一次获取N个结果,而不是一步获取所有结果。
libdbi
没有为SQL游标提供抽象,因此需要使用SQL查询来完成。
文档page on FETCH在其示例中有完整的查询序列,显示了它是如何完成的。你需要在C语言中使用带有两个循环的libdbi来调用这些查询:一个外部循环调用FETCH N from cursor_name
,直到没有任何内容可以获取,一个内部循环处理该FETCH的结果,就像你当前的代码一样处理select *
本身的结果。