【问题标题】:SQLite VACUUM in parallel thread并行线程中的 SQLite VACUUM
【发布时间】:2013-10-17 11:06:09
【问题描述】:

尝试优化我的应用程序数据库工作。

在数据库同步期间,我的应用程序在一个事务中运行一大包“删除”和“插入”命令。在事务‘COMMIT’应用程序运行‘VACUUM’命令之后。 VACUUM 工作正常,但有时需要很多时间。 所以我决定在并行线程中移动'VACUUM'执行。这里出了点问题。在其他线程中,我得到“数据库已锁定”。

我做什么:

1.COMMIT成功后关闭数据库。

2. 使用 'VACUUM' 再次启动打开和关闭数据库的单独方法。

在“COMMIT”的同一线程中,“VACUUM”工作正常,但在单独的线程中,相同的方法会出现“数据库已锁定”错误。 我可以肯定地说,没有其他进程适用于封闭数据库,因为数据库同步是一个逻辑上独立的应用程序进程。

我做错了什么?

    [connection closeDb];
    [connection release];

    if(!rollBackTransaction && commitSuccess){
// The commented code block doesn't work - "database is locked" error
//        NSThread *thread=[[NSThread alloc] initWithTarget:self selector:@selector(runVacuumForDataBase:) object:_dbFileName];
//        [thread start];
        [self runVacuumForDataBase:_dbFileName]; // <-- This works fine
    }

【问题讨论】:

  • VACUUM 密集使用数据库。我认为 SQLite 重写了所有数据库。因此,请限制您的 Vacuum 调用并使用内存表进行中间操作。
  • 你认为为什么需要运行 VACUUM?
  • 应用程序适用于大型数据库——10-20 Mb,查询时间很关键。我在这里放了一个简化的代码片段。它分析 SQL 命令并在需要时运行 VACUUM。
  • 20 MB 不算大,SQLite 会自动重用释放的页面。你有没有测量过没有 VACUUM 会发生什么?

标签: iphone ios multithreading sqlite vacuum


【解决方案1】:

您只能从一个线程同时访问 SQLite 数据库。在您的情况下,在不同的线程上执行 VACUUM 将不起作用,您必须等到第一个事务完成。祝你好运!

编辑在使用多线程环境时,我遇到了与您相同的问题。我最终为 SQLite db 使用了调度队列,其中所有到 db 的事务都是同步运行的。我强烈建议您将所有请求移到数据库中的不同线程(辅助线程,而不是主线程)。

【讨论】:

  • “连接关闭”不能保证交易完成吗?我之前说过事务提交并关闭连接。
  • 只看上面的代码片段,新的并行线程在数据库连接关闭和释放后启动。然后当前线程继续使用其他数据库,新线程尝试仅使用真空。
  • 在执行真空请求之前添加一些时间间隔。
猜你喜欢
  • 2014-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
相关资源
最近更新 更多