0

libdbi を使用して大規模な postgresql データベース (3 億レコード) に接続し、SELECT *クエリを実行してから、結果を 1 行ずつ表示します。完全なスワップとメモリを取得しているため、autocommit有効になっているようで、結果セット全体がメモリにロードされます。ResultSet.HOLD_CURSORS_OVER_COMMITjavaのようにコミット後に自動コミットを無効にするか、少なくともカーソルを保持するオプションはありますか? それを行うためのオプションが見つかりませんでし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();
4

1 に答える 1

1

自動コミットとは関係ありません。

メモリ不足の問題の解決策は、一度にすべての結果を取得するのではなく、カーソルを使用して一度に N 個の結果を取得することです。

libdbiは SQL カーソルの抽象化を提供しないため、SQL クエリで行う必要があります。

ドキュメンテーションのFETCH のページには、その例でクエリの完全なシーケンスがあり、それがどのように行われたかを示しています。これらのクエリは C で libdbi を使用して 2 つのループで呼び出す必要があります。FETCH N from cursor_name取得するものがなくなるまで呼び出す外側のループと、その FETCH の結果を処理する内側のループです。現在のコードがselect *それ自体の結果を処理するのと同じです。

于 2012-08-07T14:07:54.580 に答える