为什么InsertHelper被弃用了?

12

我一直在研究我们设备的一些性能问题,发现我们有相当多的应用程序都在进行数据库读写操作。

我首先使用联系人API插入新联系人和数据行,但速度非常慢。插入大约1500行(250个原始联系人和1250个数据行)需要1分18秒。

我曾在另一个应用程序中使用过插入帮助程序来实现高效的插入,于是决定编写一个测试应用程序,用不同的插入方法写入到不同的数据库中。

每个数据库都有一个表,每个表都有4列: _ID、Name、Time和Blob(全部为“string”类型),就像联系人提供程序定义的数据列一样。

_ID是自动递增的主键,Name只插入相同的内容“1234567890”,时间只是当前系统时间的毫秒表示,而BLob则是一个长度为6400的字符串,其中包含字母“A”...

我首先检查了批量插入,但它只是循环遍历您定义的所有插入,并且与单独插入(或可忽略的性能影响)一样慢。

我测试了3种不同的插入方法: ContentValues使用db.insert方法: SQLiteStatement使用statement.execute()(在事务内完成)。 SqliteInsertHelper使用事务。

我可以提供一些代码,但我从InsertHelper中获得了最佳性能,并想知道为什么它已被弃用:

插入100条记录所需的时间 ContentValues:7.778秒(每毫秒写入82字节) SQLiteStatement:1.311秒(每毫秒写入489字节) SqliteInsertHElper:0.292秒(每毫秒写入2197字节)

有什么想法吗?


我进行了一些额外的测试, 并进行了常规插入操作,但将其作为事务的一部分,这大大提高了性能。看起来可能需要一些代码以产生(看联系人提供者)。 - Chrispix
鉴于您提到的性能问题,事务将是我的首要建议(每个事务都需要往返IO等待,每个事务之外的插入操作都会隐式包装在其中)。除此之外,这篇文章可能会有所帮助:https://dev59.com/hGYq5IYBdhLWcg3woB0W - rutter
我也会建议使用事务。我测试过带有事务的插入速度相当快。 - Luis
3个回答

7
很难找到关于为什么InsertHelper被弃用的任何信息,除非查看实际进行弃用的提交。弃用InsertHelper的工程师给出了以下理由:
这个类与SQLiteStatement相比没有任何优势,只会使代码更加复杂和容易出错。
从InsertHelper重构到SQLiteStatement后,我同意这一点。唯一的例外是针对空值安全绑定函数。虽然InsertHelper会自动为您调用bindNull(),但如果您传递一个空字符串并且在调用bindString()之前必须进行自己的空检查,SQLiteStatement会崩溃。

See: https://android.googlesource.com/platform/frameworks/base/+/b33eb4e%5E!/


点赞你去提交日志获取权威答案。如果可以的话,我还会给你更多的。 - Dalbergia

0

你应该使用事务。如果你没有为数据库操作显式地创建一个事务,框架会为每个操作创建一个事务。将你的对象分组并一次性插入它们。这将大大提高性能。


0
InsertHelper允许用户使用相同的语句对表进行多次插入。但是,由于它不是线程安全的,因此这不是一个好的插入方式。

5
根据http://developer.android.com/reference/android/database/sqlite/SQLiteStatement.html,替代建议也不具有线程安全性。 - Evan R.

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