安卓ContentProvider插入数据需要很长时间

7
我创建了自己的ContentProvider,使用多个插入操作一次性插入了大量数据。
应用程序从外部源接收数据,目前每次接收约30个项目(因此需要进行30次插入)。
现在我注意到这需要很多宝贵的时间(大约3秒钟,每个插入操作需要100毫秒)。
我该如何提高ContentProvider的速度?我已经尝试将它们全部bulkInsert在一起,但这将需要长达5秒钟。
提前感谢。

如果您在Android 2.1或更低版本中使用内容提供程序,即使使用事务,也不要指望能够在1或2秒内进行批量插入。SQLite实现非常缓慢。 - Dalmas
谢谢,但我正在使用2.2版本。所以应该没问题。 - Ion Aalbers
有时候问题可能出在插入语句上。为了检查这个问题,你可以使用SQLiteBrowser打开你的数据库,并执行相同的插入语句,看看是否也需要很长时间? - Sunil Kumar Sahoo
2个回答

21

把所有操作都包装在 insertBulk 中并且放到事务中。

例如:

    SQLiteDatabase sqlDB = mDB.getWritableDatabase();
    sqlDB.beginTransaction();
    try {

        for (ContentValues cv : values) {
            long newID = sqlDB.insertOrThrow(table, null, cv);
            if (newID <= 0) {
                throw new SQLException("Failed to insert row into " + uri);
            }
        }
        sqlDB.setTransactionSuccessful();
        getContext().getContentResolver().notifyChange(uri, null);
        numInserted = values.length;
    } finally {
        sqlDB.endTransaction();
    }

bulkInsert默认情况下不使用事务,因为默认行为只调用insert

覆盖此方法以处理插入一组新行的请求,否则默认实现将遍历值并在每个值上调用insert(Uri, ContentValues)


在那个完全可用的示例中,查询Uri以提供适当的table变量。 - davidcesarino
1
谢谢!这真的解决了问题!它只用了110毫秒,而不是3秒。 - Ion Aalbers
不客气。那个示例实际上来自我拥有的一段代码。 :-) - davidcesarino

3

在事务中执行插入操作可以极大地提高速度,因为实际数据库只进行一次写操作:

db.beginTransaction();
try {
    // do the inserts
    db.setTransactionSuccessful()
} finally {
    db.endTransaction();
}

我曾经进行实验,试图提高 ~2000 次写入的速度,这是我找到的唯一一个很大的改进。
执行 db.setLockingEnabled(false) 可能会带来约 1% 的改进,但是您必须确保没有其他线程写入数据库。如果表格非常大,则删除冗余索引也可以提供微小的提升。

感谢您的快速回复。 - Ion Aalbers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接