2023年9月22日 星期五

[C++ ]Poco資料寫入資料庫SQLite解析

  Poco::Data::SQLite::Connector::registerConnector();

    // 建立会话

    Session session("SQLite", "sample.db");

    // 如果有名為abc的表存在,删除

    session << "DROP TABLE IF EXISTS abc", now;

    // 創建Table

    session << "CREATE TABLE abc (Name VARCHAR(30), Address VARCHAR, Age INTEGER(3))", now;

     Statement insert(session);

  //塞一筆資料 #略#

for(int i=0; i<=65535; i++)

{

    insert << "INSERT INTO abc VALUES(?, ?, ?)",use(abc.name),use(abc.address),use(abc.age);

   //在這裡每插入一筆資料 必須使用insert.exexute(); 並執行execute方法

    insert.execute();

}
當使用for loop 時 insert必須都在括弧內宣告及處理,execute使用for loop會造成效能低下

65536筆跑完必須耗時10分鐘

有關于SQLite批量寫入資料耗時的問題有很多帖子可以找

我找到這篇Reference : https://blog.darkthread.net/blog/sqlite-insert-slow/


在UnitTest時 為了達到65536筆資料來滿足line coverage必須花不少時間,因此需要介紹以下的批量寫入

在訪問了Bing大神後(Bing也有推薦此篇文章 : Poco插入大量数据到数据库的优化 | xilixili.net),有找到一種寫法 說是批量寫入需要靠"事務"進行優化

其範例程式碼如下 : 

Poco::Data::Session sess("SQLite", "test.db");
sess << "create table if not exists test ("
        " [col_a] NVARCHAR (256) NOT NULL,"
        " [col_b] NVARCHAR (256) NOT NULL)",
    Poco::Data::Keywords::now;
 
sess.begin();  <=============================重點在這兩筆
for (size_t i = 0; i < 65535; i++) {
    char bufa[64] = {0};
    char bufb[64] = {0};
    sprintf(bufa, "test col a %d %d", i, rand());
    sprintf(bufb, "test col b %d %d", i * 2, rand());
    sess << "insert into test (col_a,col_b) values (?,?)",
        Poco::Data::Keywords::use(bufa),
        Poco::Data::Keywords::use(bufb),
        Poco::Data::Keywords::now;
}
sess.commit();  <=============================重點在這兩筆

中間筆數內的詳細資訊可以略過,因個人專案不同而已 當使用for loop進行插入前後必須宣告

sess.begin(); 以及 sess.commit(); 便可快速且大量塞入資料至Poco資料庫SQLite中


沒有留言:

張貼留言