2012-01-26 12 views
0

cアプリケーションからmysqlデータベースに多数の整数と浮動小数点を入れなければなりません。mysql c api:数値を文字列に変換せずに挿入する

は現在、私は文字列にすべてのそれらの値を変換し、データベースにそれらを転送することでこれをやっている:この方法として

char * sql_query[2048]; 
sprintf(sql_query, "INSERT INTO my_table VALUES (%u, %u, %d, %.7f, %u, ....."); 
if (mysql_real_query(&mysql, sql_query, strlen(sql_query)) { 
    fprintf(stderr, "SQL Request failed: Error: %s\n", mysql_error(&mysql)); 
} 

を非常に時間がかかるものである:そこ変換を回避するための方法ではありませんmysqlによって解釈され、変換される必要のある文字列に変換します。 バイナリAPIを探しています。私の変数を直接呑み込んでいます。それは存在しますか?

答えて

2

sprintf()が発生するオーバーヘッドは、Mysqlに送信している個々のINSERTのgazillionsによって覆い隠されます(あなたが私を信じていない場合は、アプリケーションのプロファイリングを試してみてください)。言い換えれば、高いスループットを求めている場合、間違った場所で最適化する可能性が非常に高いです。

あなたのすべてのレコードをCSVファイル(私はパイプ区切りを使用しています)に書き込んだ後、LOAD DATA INFILE(速度を大幅に最適化しています)経由でバッチ全体を読み込みます。これらのタイプのツールは、Sybaseのbcp(一括コピー)ユーティリティから数十年前から使用されてきました。

最初は、2つのステップ(ファイルへの書き込みとロード)が遅くなるように見えますが、1つの巨大な負荷の低オーバーヘッドは、個々のINSERTトランザクションの洪水でデータベースを叩くコストに簡単に打ち勝ちます。

私は、CSVとLOAD DATA INFILEを使用して、Cから、またはRubyのようなスクリプト言語を使って、何百万ものレコードをすばやく読み込みました。

小数点以下のレコードしかない場合は、現在のアプローチは完全に優れています。スキーマが変更された場合やMysql以外のサーバーに移植する場合は、簡単に保守が可能です。

1

あなたが使用できる文:

http://dev.mysql.com/doc/refman/5.0/en/c-api-prepared-statement-type-codes.html

http://dev.mysql.com/doc/refman/5.0/en/c-api-prepared-statement-function-overview.html

http://dev.mysql.com/doc/refman/5.0/en/c-api-prepared-statement-data-structures.htmlしかし、あなたはおそらく一つの大きな問合せにINSERTクエリを組み合わせることにより、より高いパフォーマンスを得ることが

http://dev.mysql.com/doc/refman/5.0/en/c-api-multiple-queries.html

また

あなたがsnprintf()を使用していない気づいた、私は強く、それを使用することをお勧め:

snprintf(query,sizeof(query),...) 

はsnprintfからのオーバーヘッドが偶数倍と比較して始めることができないためには、mysql_real_query()

編集呼び出し、

関連する問題