Hi,
we are seeing a drastic performance loss after using SQLCipher 4.2 in our android app.
Even in case we don’t provide an encryption key and just use SQLCipher without encryption
our app performances about 300 percent slower as if we use the FrameworkSQLite Database.
There is already an post on stackoverflow regarding this issue: https://stackoverflow.com/questions/58954634/sqlcipher-4-2-is-300-solwer-even-if-encryption-is-not-active-android
- Are there any connection parameter that we could try to change to boost the performance?
- What is the difference between the native sqlLite engine that is shipped with Android and the one that is used by SqlCipher?
For example this query:
SELECT id FROM tableTest;
takes about 8600 ms to finish
where tableTest is defined by:
CREATE TABLE IF NOT EXISTS tableTest (id BIGINT NOT NULL PRIMARY KEY, smallText VARCHAR, mediumText VARCHAR);
with about 76 000 rows, smallText is less than 20 chars wide and mediumText is less than 300 chars wide
- target sdk is 29
- the device we are testing on is a samsung T515 tablet
- we don’t see much cpu usage in the profiler
this is how we define import sqlcipher android wrapper:
repositories {
flatDir {
dirs 'libs/aars'
}
}
dependencies {
...
implementation (name:'android-database-sqlcipher-4.2.0-release', ext:'aar')
...
}
this is how we open the database:
public SupportSQLiteOpenHelper getDatabase(final DatabaseIdentifier identifier, final DatabaseDefinition databaseDefinition) throws IOException, GeneralSecurityException {
SupportSQLiteOpenHelper.Factory factory;
final int sqliteEngine = databaseDefinition.getSqliteEngine();
if (sqliteEngine == DatabaseDefinition.SQLITE_ENGINE_ANDROID_FRAMEWORK) {
factory = new FrameworkSQLiteOpenHelperFactory();
}
else if (sqliteEngine == DatabaseDefinition.SQLITE_ENGINE_SQLCIPHER) {
final SQLiteDatabaseHook sqlCipherHook = new SQLiteDatabaseHook() {
@Override
public void preKey(final net.sqlcipher.database.SQLiteDatabase sqLiteDatabase) {
}
@Override
public void postKey(final net.sqlcipher.database.SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.rawExecSQL("PRAGMA cipher_memory_security = OFF;");
}
};
if (databaseDefinition.isSqlCipherEncrypted()) {
factory = new SupportFactory(databaseDefinition.getSqlCipherEncryptionKey(), sqlCipherHook);
}
else {
factory = new SupportFactory(new byte[0], sqlCipherHook);
}
}
else {
throw new AssertionError();
}
final SupportSQLiteOpenHelper.Callback callback = new SupportSQLiteOpenHelper.Callback(1) {
@Override
public void onCreate(final SupportSQLiteDatabase db) {
}
@Override
public void onUpgrade(final SupportSQLiteDatabase db, final int oldVersion, final int newVersion) {
}
@Override
public void onOpen(final SupportSQLiteDatabase db) {
super.onOpen(db);
....
}
};
final SupportSQLiteOpenHelper.Configuration configuration = SupportSQLiteOpenHelper.Configuration
.builder(mApplication)
.name(databaseDefinition.getPath())
.callback(callback)
.build();
return factory.create(configuration);
}