Cómo insert 40000 loggings rápidamente en una database sqlite en un iPad

Quiero insert 40000 loggings que obtengo de un service web en una database sqlite en mi aplicación iPad.

Escribí el siguiente código, pero lleva unos 20 minutos, ¿hay una manera más rápida?

- (NSArray *)insertPriceSQLWithPrice:(Price *) price { SQLiteManager *dbInfo = [SQLiteManager shanetworkingSQLiteManagerWithDataBaseName:@"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 insert en la base de datps"); } else NSLog(@"Error %@ ERROR!!!!",querySQL); sqlite3_finalize(compiledStatement); } sqlite3_close(database); return nil; } 

Hay dos cosas que debe hacer para acelerar las inserciones:

  • Mueva la llamada de sqlite3_open fuera del ciclo. Actualmente, el bucle no se muestra, así que supongo que está fuera del fragment de código
  • Agregue las llamadas BEGIN TRANSACTION y COMMIT TRANSACTION : debe comenzar la transacción antes del bucle de inserción y finalizarla justo después de que finalice el bucle.
  • Haga que formatStringQueryInsertWithTable realmente parametrizado : actualmente parece que no está utilizando declaraciones preparadas al máximo, porque a pesar de usar sqlite3_prepare_v2 , no tiene llamadas de sqlite3_bind_XYZ en su código.

Aquí hay una buena publicación que muestra cómo hacer todo lo anterior . Es C simple, pero funcionará bien como parte de un progtwig 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); 

Para mí, llamar a BEGIN TRANSACTION y luego cargar unos 20 insertos, luego llamar a COMMIT TRANSACTION dio un aumento de performance de 18x, ¡buen consejo! Cachear las declaraciones preparadas fue de poca ayuda.