2012-05-11 6 views
2

Oracle OCIおよびOCCIには、クライアントに値の配列を作成し、この配列を準備文とともにサーバーに送信して何千ものエントリを挿入するためのAPI配列があります1回のショットでテーブルを作成することで、いくつかのシナリオで大きなパフォーマンスが向上します。 PostgreSQLに類似したものはありますか?Postgresの高速配列挿入

私はPostgreSQL C APIを使用しています。

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

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() 
+1

どの言語/ PostgreSQLクライアントAPIを使用していますか?これにより、どの機能を簡単に使用できるかが異なります。 – Edmund

答えて

3

PostgreSQLは、同様の機能がある - ステートメントCOPYとCOPYのAPIを - それは

libpq documentation

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); 
+0

データは常にタブで区切られた値の行ですか? 1つの列がvarcharの場合は、引用符で囲むか、おそらくPQエスケープ関数を呼び出す必要がありますか? – Waslap

+0

デリミタのような任意の文字を使用できます。タブはデフォルトの区切り文字です - COPYのドキュメントを参照してください。http://www.postgresql.org/docs/9.1/static/sql-copy.html –

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を頻繁に交換しました。かなりシームレスです。

+0

データを入れる必要があるのは残念です最初にファイル。私の場合、私はコード化されたファイルを受け取り、ファイルから値をデコードし、それらをメモリから直接挿入したい。それらを新しい(PostgreSQLのコピーされた)ファイルに戻すことは残念です。 – Waslap

+0

いいえ、ストリームでCOPYを使用することも、文字列内のデータ行で直接使用することもできます。 –

1

私は、単一のコマンドで数千行を作成するためのこの方法を好む:

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

バインド$1に列1の値の配列、$2などへのカラム2の値の配列!列で値を指定すると、行を考えるのに慣れたときに最初はちょっと変わって見えるかもしれません。

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