2013-01-31 11 views
7

Voglio inserire 40000 record che ottengo da un servizio Web in un database SQLite nella mia app per iPad.Come inserire rapidamente 40000 record in un database sqlite in un iPad

Ho scritto il seguente codice, ma ci vogliono circa 20 minuti, c'è un modo più veloce?

- (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

Prenderei l'apertura e la chiusura del database fuori dal metodo. Ti sta costando una buona quantità di tempo. Creare e mantenere il connectoin attraverso ciascuno dei 40.000 inserti e quindi distruggerlo una volta completato. Inoltre, NSLogs potrebbe rallentare l'esecuzione effettiva. Proverei a eseguire uno senza i registri per vedere quanto tempo ci vuole. – Jeremy1026

+0

Riapri il database 40000 volte? (Si dovrebbe anche evitare di ricompilare la dichiarazione una volta per record, ed è meglio fare tutti gli inserimenti in una singola transazione, ma è meno importante della riapertura per ogni riga). –

+2

È possibile inserire più righe per inserto con la query corretta e avvolgere l'intero processo in una transazione: al momento SQLite deve eseguire lo svuotamento su disco dopo ogni inserimento che rallenterà il processo verso il basso. È inoltre possibile riutilizzare l'istruzione preparata, riconciliando nuovamente i valori modificati ogni volta –

risposta

22

Ci sono tre cose che dovete fare per accelerare le inserzioni:

  • spostare la chiamata del sqlite3_open fuori del ciclo. Attualmente, il ciclo non viene mostrato, quindi suppongo che sia al di fuori frammento di codice
  • Aggiungi BEGIN TRANSACTION e COMMIT TRANSACTION chiamate - è necessario iniziare la transazione prima che il ciclo di inserimento e terminarla a destra dopo il ciclo è finito.
  • Marchio formatStringQueryInsertWithTable veramente parametrizzato - Attualmente sembra che non si utilizza istruzioni preparate al loro massimo, perché nonostante l'uso di sqlite3_prepare_v2, si dispone di nessuna chiamata di sqlite3_bind_XYZ nel codice.

Ecco a nice post that shows you how to do all of the above. È semplice C, ma funzionerà bene come parte di un programma 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

Per me, chiamando BEGIN TRANSACTION quindi il caricamento di circa 20 inserti, quindi chiamando COMMIT operazione ha un aumento delle prestazioni 18x - grande punta! Il caching delle dichiarazioni preparate è stato di scarso aiuto.

Problemi correlati