2012-01-26 19 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)); 
} 

由於這種方式是相當耗時:

目前,我通過將所有這些值轉換成字符串,然後將它們transfering到數據庫中這樣做是不是有沒有辦法避免的轉換字符串,需要解釋並由mysql轉換回來。 我正在尋找一個二進制API,它直接吞下我的變量。這是否存在?

回答

2

由於您發送給Mysql的單個插入程序(如果您不相信我,請嘗試對您的應用程序進行分析),sprintf()將因此而變得黯然失色。換句話說,如果您正在尋找更高的吞吐量,您很可能會在錯誤的地方進行優化。

一個更好的方法是將所有記錄寫入CSV文件(我使用管道分隔符),然後通過LOAD DATA INFILE(它已經針對速度進行了大量優化)加載整個批次。這些類型的工具已經使用了數十年,從Sybase的bcp(批量複製)實用程序開始一直使用這些工具。起初,看起來採取兩個步驟(寫入文件然後加載)會比較慢,但是一個巨大負載的低開銷通過大量單獨的INSERT事務輕鬆地擊敗數據庫的成本。

我已經使用CSV和LOAD DATA INFILE快速加載了數百萬條記錄,從C或像Ruby等腳本語言一樣快,因爲服務器將完成大部分繁重工作。 Otoh,如果您只有少數記錄,那麼您當前的方法非常好:在模式更改或您決定移植到除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-data-structures.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-multiple-queries.html

因爲snprintf的開銷甚至不能開始比較多mysql_real_query()調用

編輯:

也沒有使用snprintf()注意到,我強烈建議使用它:

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