7

Web サービスから取得した 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;
}
4

2 に答える 2

23

挿入を高速化するには、次の 3 つのことを行う必要があります。

  • の呼び出しをsqlite3_openループ外に移動します。現在、ループは表示されていないため、コード スニペットの外側にあると想定しています
  • 追加BEGIN TRANSACTIONCOMMIT TRANSACTION呼び出し - 挿入ループの前にトランザクションを開始し、ループが終了した直後に終了する必要があります。
  • 真にformatStringQueryInsertWithTableパラメータ化されたものにする - 現在、準備されたステートメントを最大限に使用しsqlite3_prepare_v2ていないようsqlite3_bind_XYZです.

これは、上記のすべてを行う方法を示す素晴らしい投稿です。単純な 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);
于 2013-01-31T17:34:15.587 に答える