Android SQLite:带有附加数据库的预写日志记录(WAL日志模式)

Android SQLite:带有附加数据库的预写日志记录(WAL日志模式),android,multithreading,sqlite,wal,Android,Multithreading,Sqlite,Wal,在数据库优化方面,我们将数据库分为两个数据库:db和db2。一个低优先级的后台线程正在插入db2。db上的一些查询与db2连接,因此我们需要将db2连接到db。我们之所以启用WAL,是因为我们希望它都是多线程的 SQLiteDatabase db = SQLiteDatabase.openDatabase(dbPath, ...); db.enableWriteAheadLogging(); db.execSQL("attach " + db2path + " as db2"); 为了理解这个

在数据库优化方面,我们将数据库分为两个数据库:db和db2。一个低优先级的后台线程正在插入db2。db上的一些查询与db2连接,因此我们需要将db2连接到db。我们之所以启用WAL,是因为我们希望它都是多线程的

SQLiteDatabase db = SQLiteDatabase.openDatabase(dbPath, ...);
db.enableWriteAheadLogging();
db.execSQL("attach " + db2path + " as db2");
为了理解这个问题,我们运行了一个简单的两线程测试。第一个线程将行插入数据库,第二个线程从数据库中选择。每个线程打印上一个循环的时间增量和我们在数据库中的时间

thread 1 loop:                             | thread 2 loop:
    t1 = getTime()                         |   t1 = getTime()
    db2.execSQL("insert into ....");       |   db2.execSQL("select ....");
    t2 = t3                                |   t2 = t3
    t3 = getTime()                         |   t3 = getTime()
    log("i: "+(t3-t1)+", delta: "+(t2-t1)) |   log("s: "+(t3-t1)+", delta: "+(t2-t1))
我们看到的是,选择线程阻塞了插入线程。这可以通过做一个大而慢的选择和一个小的插入来强调。您将看到插入时间和增量大约增加到选择时间。如果我们不运行慢速线程,插入线程的速度会大大加快

深入研究SQLiteDatabase的源代码,我在SQLiteDatabaseenableWriteAheadLogging中发现了以下几行代码:

现在回答我的问题:

评论的意思是什么?到底是什么不起作用?这是遗留下来的旧代码吗?ATTACH数据库的文档明确指出ATTACH+WAL是可以的,但有一点需要注意

为什么Android绑定代码试图保护我们免受SQLite内部问题的影响?在我看来,它应该是一个很薄的界面层


编辑:我在中报告这是一个bug。如果有答案出现,将进行更新。

WAL允许读者和作者同时使用,但只能通过不同的连接。决不能使用同一个连接从多个线程连接SQLiteDatabase对象

墙设置是永久性的;不需要每次打开数据库后都执行它

thread 1 loop:                             | thread 2 loop:
    t1 = getTime()                         |   t1 = getTime()
    db2.execSQL("insert into ....");       |   db2.execSQL("select ....");
    t2 = t3                                |   t2 = t3
    t3 = getTime()                         |   t3 = getTime()
    log("i: "+(t3-t1)+", delta: "+(t2-t1)) |   log("s: "+(t3-t1)+", delta: "+(t2-t1))
评论的意思正是它所说的。没有人保证这一评论是正确的

有时,Android框架试图变得聪明。但是您可以手动执行PRAGMA journal\u mode=WAL


WAL允许读者和作者同时阅读,但只能通过不同的连接。决不能使用同一个连接从多个线程连接SQLiteDatabase对象

墙设置是永久性的;不需要每次打开数据库后都执行它

thread 1 loop:                             | thread 2 loop:
    t1 = getTime()                         |   t1 = getTime()
    db2.execSQL("insert into ....");       |   db2.execSQL("select ....");
    t2 = t3                                |   t2 = t3
    t3 = getTime()                         |   t3 = getTime()
    log("i: "+(t3-t1)+", delta: "+(t2-t1)) |   log("s: "+(t3-t1)+", delta: "+(t2-t1))
评论的意思正是它所说的。没有人保证这一评论是正确的

有时,Android框架试图变得聪明。但是您可以手动执行PRAGMA journal\u mode=WAL


你不明白我的问题。我说的是SQLiteDatabase对象的源代码。除了它的作者之外,没有人能像写的那样回答这些问题。你不理解我的问题。我说的是SQLiteDatabase对象的源代码,除了它的作者之外,没有人能像写的那样回答这些问题。