2013-01-31 54 views
7

我想将我从Web服务获得的40000条记录插入到我的iPad应用程序中的sqlite数据库中。如何将40000条记录快速插入到iPad中的sqlite数据库中

我写了下面的代码,但大约需要20分钟,有没有更快的方法?

- (NSArray *)insertPriceSQLWithPrice:(Price *) price 
{ 

SQLiteManager *dbInfo = [SQLiteManager sharedSQLiteManagerWithDataBaseName:@"codefuel_catalogo.sqlite"]; 


sqlite3 *database; 

NSString *querySQL=[self formatStringQueryInsertWithTable:@"prices_list" andObject:price]; 


if(sqlite3_open([dbInfo.dataBasePath UTF8String], &database) == SQLITE_OK) 
{ 
    sqlite3_stmt * compiledStatement; 


    const char *query_stmt = [querySQL UTF8String]; 

    int result = sqlite3_prepare_v2(database, query_stmt, -1, &compiledStatement, NULL); 

    if (result == SQLITE_OK) 
    { 
     int success = sqlite3_step(compiledStatement); 

     NSLog(@"el numero de success es -> %i",success); 
     if (success == SQLITE_ERROR) 
      NSLog(@"Error al insertar en la base de datps"); 

    } 
    else 
     NSLog(@"Error %@ ERROR!!!!",querySQL); 

    sqlite3_finalize(compiledStatement); 
} 

sqlite3_close(database); 
return nil; 
} 
+8

我会把数据库的打开和关闭放在方法之外。这花费了相当长的时间。通过每个40,000个插入创建并坚持connectoin,然后在完成后将其销毁。另外,NSLogs可能会减慢实际执行速度。我会尝试运行一个没有日志来看看需要多长时间。 – Jeremy1026

+0

你重新打开数据库40000次吗? (您还应该避免每条记录重新编译一次语句,最好在单个事务中执行所有插入操作 - 但这比重新打开每行更重要)。 –

+2

您可以使用正确的查询为每个插入插入多行,并将整个进程包含在一个事务中 - 此时SQLite必须在每次插入后刷新到磁盘,这会使您放慢速度。您也可以重新使用准备好的语句,每次重新绑定更改的值 –

回答

22

还有,你需要为了做加快插入三件事情:

  • 移动的sqlite3_open通话外循环。目前,循环没有显示,所以我认为这是外界您的代码段
  • 添加BEGIN TRANSACTIONCOMMIT TRANSACTION电话 - 你需要插入循环之前开始交易,结束后立即循环已经结束。
  • 制作formatStringQueryInsertWithTable真正参数 - 目前看来,你不使用准备好的语句,以最充分的,因为尽管使用sqlite3_prepare_v2,你在你的代码中没有的sqlite3_bind_XYZ电话。

这里是a nice post that shows you how to do all of the above。它是纯C语言,但它可以很好地作为Objective C程序的一部分。

char* errorMessage; 
sqlite3_exec(mDb, "BEGIN TRANSACTION", NULL, NULL, &errorMessage); 
char buffer[] = "INSERT INTO example VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)"; 
sqlite3_stmt* stmt; 
sqlite3_prepare_v2(mDb, buffer, strlen(buffer), &stmt, NULL); 
for (unsigned i = 0; i < mVal; i++) { 
    std::string id = getID(); 
    sqlite3_bind_text(stmt, 1, id.c_str(), id.size(), SQLITE_STATIC); 
    sqlite3_bind_double(stmt, 2, getDouble()); 
    sqlite3_bind_double(stmt, 3, getDouble()); 
    sqlite3_bind_double(stmt, 4, getDouble()); 
    sqlite3_bind_int(stmt, 5, getInt()); 
    sqlite3_bind_int(stmt, 6, getInt()); 
    sqlite3_bind_int(stmt, 7, getInt()); 
    if (sqlite3_step(stmt) != SQLITE_DONE) { 
     printf("Commit Failed!\n"); 
    } 
    sqlite3_reset(stmt); 
} 
sqlite3_exec(mDb, "COMMIT TRANSACTION", NULL, NULL, &errorMessage); 
sqlite3_finalize(stmt); 
5

对于我来说,调用BEGIN TRANSACTION然后加载一些20插入,然后调用COMMIT TRANSACTION了18倍的性能提升 - 伟大的小费!缓存准备好的语句没有多大帮助。

相关问题