如何优化SQLcipher性能?

时间:2015-11-02 10:53:27

标签: ios sqlite sqlcipher

我在我的应用程序中使用SQLCipher来加密sqlite数据库。但是我的应用程序在获取数据库时运行缓慢。我将 PRAGMA kdf_iter 更改为4000并且它仍然很慢。我没有任何问题。

-(NSError *) openDatabase {

    NSError *error = nil; 
    NSString *databasePath = [self getDatabasePath];

    const char *dbpath = [databasePath UTF8String];   
    int result = sqlite3_open_v2 (dbpath, &db , SQLITE_OPEN_READWRITE , NULL);
    if (result == SQLITE_OK) {

        sqlite3_exec(db, [@"PRAGMA kdf_iter = '4000';" UTF8String], NULL, NULL, NULL);
        sqlite3_exec(db, [@"PRAGMA key = 'password'" UTF8String], NULL, NULL, NULL);

        NSLog(@"Password is correct , Database is Activated");
        sqlite3_exec(db, [@"PRAGMA cipher = 'aes-256-cfb';" UTF8String], NULL, NULL, NULL);

    }
    else {
        NSLog(@"Incorrect password!");
    }
    if (result != SQLITE_OK) {
        const char *errorMsg = sqlite3_errmsg(db);
        NSString *errorStr = [NSString stringWithFormat:@"The database could not be opened: %@",[NSString stringWithCString:errorMsg encoding:NSUTF8StringEncoding]];
        error = [self createDBErrorWithDescription:errorStr andCode:kDBFailAtOpen];

    }

    return error;
}

2 个答案:

答案 0 :(得分:2)

最后,我可以使用Nick Parker有用的指导优化我的 SQLCipher性能

正如他所说:

最佳SQLCipher性能有一些非常重要的指导原则:

  • 不要反复打开和关闭连接,因为密钥推导是非常昂贵的设计。频繁打开/关闭数据库连接(例如,针对每个查询)是性能问题的常见原因,通常可以使用单例数据库连接轻松解决。
  • 使用事务来包装插入/更新/删除操作。除非在事务范围内执行,否则每个操作都将在它自己的事务中发生,这会使事情减慢几个数量级。
  • 确保您的数据已规范化(即,使用良好做法将数据分成多个表以消除冗余)。不必要的数据重复导致数据库膨胀,这意味着SQLCipher可以运行更多页面
  • 确保索引用于搜索或加入条件的所有列。如果不这样做,SQLCipher将需要跨大量页面执行完整数据库扫描
  • 定期吸尘以确保数据库紧凑,如果您进行大量删除,更新等。

要诊断特定查询语句的性能问题,针对特定查询运行 explain query plan 命令可能会有所帮助。

如果您不确定哪些查询性能不佳,SQLCipher包含一个名为 cipher_profile 的编译指示,它允许以毫秒为单位分析查询及其各自的执行时间。

这是Reference Link

非常感谢Nick Parker。

blog对我来说非常有用。

答案 1 :(得分:0)

为什么使用CFB模式(aes-256-cfb)而不是CBC?

我认为硬件加密不支持AES CFB,所以它可能会使用软件加密,速度可能会慢500倍。

来自文档:

  

SQLCipher使用aes-256-cbc作为默认密码和操作模式。虽然通常不推荐,但可以改变这种情况