2

Oracle OCIおよびOCCIには、配列挿入を実行するAPI機能があり、クライアントで値の配列を作成し、この配列をプリペアドステートメントとともにサーバーに送信して、数千のエントリを1回のショットでテーブルに挿入します。一部のシナリオでは、パフォーマンスが大幅に向上します。PostgreSQLに似たようなものはありますか?

標準のPostgreSQLCAPIを使用しています。

私が考えていることを説明するためのいくつかの擬似コード:

stmt = con->prepare("INSERT INTO mytable VALUES ($1, $2, $3)");
pg_c_api_array arr(stmt);
for triplet(a, b, c) in mylongarray:
    pg_c_api_variant var = arr.add();
    var.bind(1, a);
    var.bind(2, b);
    var.bind(3, c);
stmt->bindarray(arr);
stmt->exec()
4

3 に答える 3

3

PostgreSQLには同様の機能があります-ステートメントCOPYとCOPYAPI-それは非常に高速です

libpqドキュメント

char *data = "10\t20\40\n20\t30\t40";

pres = PQexec(pconn, "COPY mytable FROM stdin");

/* can be call repeatedly */ 
copy_result = PQputCopyData(pconn, data, sizeof(data));
if (copy_result != 1)
{
        fprintf(stderr, "Copy to target table failed: %s\n",
                                        PQerrorMessage(pconn));
        EXIT;
}

if (PQputCopyEnd(pconn, NULL) == -1)
{
         fprintf(stderr, "Copy to target table failed: %s\n",
                                            PQerrorMessage(pconn));
                            EXIT;
}

pres = PQgetResult(pconn);
if (PQresultStatus(pres) != PGRES_COMMAND_OK)
{
       fprintf(stderr, "Copy to target table failed:%s\n",
                                            PQerrorMessage(pconn));
           EXIT;
}

PQclear(pres);
于 2012-05-11T09:04:52.260 に答える
1

Pavel Stehuleが指摘しているように、COPYコマンドがあり、Cでlibpqを使用する場合は、コピーデータを送信するための関連関数があります。私はこれらを使用していません。私は主にPythonでPostgreSQLに対してプログラミングを行っており、psycopg2の同様の機能を使用しています。それは非常に簡単です:

conn = psycopg2.connect(CONN_STR)
cursor = conn.cursor()
f = open('data.tsv')
cusor.copy_from(f, 'incoming')
f.close()

実際、私はしばしばopen、最初にいくつかの基本的なデータクリーニングを実行するファイルのようなラッパーオブジェクトに置き換えました。それはかなりシームレスです。

于 2012-05-11T09:49:34.050 に答える
1

1つのコマンドで数千の行を作成するこの方法が好きです。

INSERT INTO mytable VALUES (UNNEST($1), UNNEST($2), UNNEST($3));

列1の値の配列をにバインドし、$1列2の値の配列をにバインドします$2。行で考えることに慣れている場合、列に値を指定することは、最初は少し奇妙に思えるかもしれません。

UNNEST配列をセットに変換するには、PostgreSQL>=8.4または独自の関数が必要です。

于 2013-06-10T09:19:12.527 に答える