gpt4 book ai didi

iphone - 批量插入到 iPhone 上的 sqlite 数据库中

转载 作者:行者123 更新时间:2023-12-03 19:40:51 25 4
gpt4 key购买 nike

我正在插入一批 100 条记录,每条记录都包含一个包含任意长 HTML 字符串的字典,天哪,速度很慢。在 iPhone 上,运行循环在此事务期间会阻塞几秒钟。我唯一的办法是使用另一个线程吗?我已经使用了几个从 HTTP 服务器获取数据,并且 sqlite 文档明确不鼓励数据库线程化,即使它应该是线程安全的......是否有一些我做的非常错误的事情,如果修复的话,会大大减少完成整个操作所需的时间?

    NSString* statement;
statement = @"BEGIN EXCLUSIVE TRANSACTION";
sqlite3_stmt *beginStatement;
if (sqlite3_prepare_v2(database, [statement UTF8String], -1, &beginStatement, NULL) != SQLITE_OK) {
printf("db error: %s\n", sqlite3_errmsg(database));
return;
}
if (sqlite3_step(beginStatement) != SQLITE_DONE) {
sqlite3_finalize(beginStatement);
printf("db error: %s\n", sqlite3_errmsg(database));
return;
}

NSTimeInterval timestampB = [[NSDate date] timeIntervalSince1970];
statement = @"INSERT OR REPLACE INTO item (hash, tag, owner, timestamp, dictionary) VALUES (?, ?, ?, ?, ?)";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, [statement UTF8String], -1, &compiledStatement, NULL) == SQLITE_OK)
{
for(int i = 0; i < [items count]; i++){
NSMutableDictionary* item = [items objectAtIndex:i];
NSString* tag = [item objectForKey:@"id"];
NSInteger hash = [[NSString stringWithFormat:@"%@%@", tag, ownerID] hash];
NSInteger timestamp = [[item objectForKey:@"updated"] intValue];
NSData *dictionary = [NSKeyedArchiver archivedDataWithRootObject:item];

sqlite3_bind_int( compiledStatement, 1, hash);
sqlite3_bind_text( compiledStatement, 2, [tag UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text( compiledStatement, 3, [ownerID UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_int( compiledStatement, 4, timestamp);
sqlite3_bind_blob( compiledStatement, 5, [dictionary bytes], [dictionary length], SQLITE_TRANSIENT);

while(YES){
NSInteger result = sqlite3_step(compiledStatement);
if(result == SQLITE_DONE){
break;
}
else if(result != SQLITE_BUSY){
printf("db error: %s\n", sqlite3_errmsg(database));
break;
}
}
sqlite3_reset(compiledStatement);
}
timestampB = [[NSDate date] timeIntervalSince1970] - timestampB;
NSLog(@"Insert Time Taken: %f",timestampB);

// COMMIT
statement = @"COMMIT TRANSACTION";
sqlite3_stmt *commitStatement;
if (sqlite3_prepare_v2(database, [statement UTF8String], -1, &commitStatement, NULL) != SQLITE_OK) {
printf("db error: %s\n", sqlite3_errmsg(database));
}
if (sqlite3_step(commitStatement) != SQLITE_DONE) {
printf("db error: %s\n", sqlite3_errmsg(database));
}

sqlite3_finalize(beginStatement);
sqlite3_finalize(compiledStatement);
sqlite3_finalize(commitStatement);

最佳答案

您需要注意的是,SQLite 文档警告您不要从多个线程访问/写入数据库。只要您从单个线程访问数据库,就可以了。该线程是程序的主线程还是其他线程并不重要。

请记住,iPhone 上 SQLite 的编译版本将其线程模式设置为“多线程”,根据 documentation ,“禁用数据库连接和预准备语句对象上的互斥。应用程序负责序列化对数据库连接和预准备语句的访问,但启用其他互斥,以便只要没有两个线程,SQLite就可以在多线程环境中安全使用尝试同时使用相同的数据库连接。”因此,如果您决定将此事务放在另一个线程上,请注意您尝试对数据库执行的其他操作。

话虽这么说,我首先遵循 Yonel 的建议并切换到“开始”和“提交”。如果这没有帮助,请将事务移至另一个线程。据我所知,使用“blob”可能会非常慢。

关于iphone - 批量插入到 iPhone 上的 sqlite 数据库中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2445915/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com