【问题标题】:Store huge data in SQLite [duplicate]在 SQLite 中存储大量数据 [重复]
【发布时间】:2013-06-26 05:44:09
【问题描述】:

我必须在 SQLite 数据库中添加大量数据,并且需要一些建议如何在 iOS 中实现该功能。我必须将大约 1 GB 的数据从服务器同步到 iPhone SQLite 数据库。

我需要其他方法在 iOS 端的数据库中存储快速数据。我试过一个一个的存储数据,但是同步和存储数据的时间太长了。

【问题讨论】:

  • 使用SQLTransaction向表中插入数据
  • 1GB 是仅用于初始同步还是重复?
  • 如果有一堆记录,事务可以提供帮助。如果你有大块,SQLite 不适合。告诉我们更多关于数据的信息,也许分享一些源代码。顺便说一句,令我震惊的是,限制因素将是从服务器中检索它,而不是保存在您的设备上。
  • 是的,找出瓶颈在哪里。很可能,如果您正在执行大量插入操作,使用事务将提供至少 10 倍的性能提升。当然,对任何重复的语句都使用准备好的语句。
  • 只是好奇,您确定要将这么多数据推送到用户的手机吗?如果它是一个商业应用程序,您可能会遇到大量用户空间不足的问题。

标签: ios objective-c sqlite


【解决方案1】:

我建议你阅读这个 Stack Overflow 问题:

How do I improve the performance of SQLite?

这是对如何提高 SQLite 性能的全面介绍,当我在 iOS 上尝试将 100,000 条记录插入 SQLite 数据库时遇到速度问题时,它非常有用。

具体而言,事务的使用显着降低了整体插入速度。这是一小段示例代码,因此您可以了解我的意思:

const char *dbpath = [[Utilities pathInDocumentsFolder: MY_DATABASE] UTF8String];
const char *sql = "INSERT INTO Filters (Region, District, Territory) " \
    "VALUES (?, ?, ?)";
sqlite3 *mapDB;
char *sqliteError;

sqlite3_stmt *insertStatement;

sqlite3_open(dbpath, &mapDB);

sqlite3_exec(mapDB, "BEGIN TRANSACTION", NULL, NULL, &sqliteError);

if (sqlite3_prepare_v2(mapDB, sql, -1, &insertStatement, NULL) == SQLITE_OK) {
    for (NSArray *row in filtersArray) {
        sqlite3_bind_text(insertStatement, 1, [[row objectAtIndex: 0] UTF8String], -1, SQLITE_TRANSIENT);  // Region
        sqlite3_bind_text(insertStatement, 2, [[row objectAtIndex: 1] UTF8String], -1, SQLITE_TRANSIENT);  // District
        sqlite3_bind_text(insertStatement, 3, [[row objectAtIndex: 2] UTF8String], -1, SQLITE_TRANSIENT);  // Territory

        if (sqlite3_step(insertStatement) != SQLITE_DONE) {
            break;
        }

        sqlite3_clear_bindings(insertStatement);
        sqlite3_reset(insertStatement);
    }
}

sqlite3_exec(mapDB, "END TRANSACTION", NULL, NULL, &sqliteError);

sqlite3_finalize(insertStatement);

sqlite3_execBEGINEND TRANSACTION 语句具有魔力。

【讨论】:

  • +1 同意。在插入大量记录时,使用事务可以将性能提高几个数量级。重新绑定也有帮助,但性能提升幅度较小。
  • 如果您没有从各种 sqlite3 函数调用中获得 SQLITE_OK 作为返回码(或者对于 sqlite3_stepSQLITE_DONE 返回码),我可能还建议您记录 sqlite3_errmsg(mapDB) )。
  • 而且,顺便说一句,您的 SQL 中有一个额外的 ? 占位符。这只是一个例子,所以没什么大不了的,仅供参考。您也不需要“\”来继续下一行代码中的字符串。如果第一行末尾没有右引号,下一行开头没有新的左引号,则只需要反斜杠。你有它的方式,反斜杠是不必要的。
猜你喜欢
  • 2016-03-26
  • 1970-01-01
  • 2018-07-22
  • 2014-06-23
  • 2015-05-26
  • 2013-06-27
  • 1970-01-01
  • 2011-07-25
相关资源
最近更新 更多