0

我测量了数据库查询,我发现它第一次运行时比所有后续查询都慢。我第一次运行下面的代码时得到:11. 对于所有后续调用,它始终是 only 1。它是如何工作的,所以在第一次查询后它会更快?

long time = System.currentTimeMillis();
Cursor cursor = DBHelper.getInstance().getAllContacts();
Logger.log(TAG, "measured time is " + String.valueOf(System.currentTimeMillis() - time));

`getAllContacts() 方法是:

(getReadableDatabase().rawQuery("SELECT _id, name, title FROM " + CONTACTS_TABLE_NAME, null));
4

2 回答 2

1

这里可能有一些影响。

首先,您还要为该getReadableDatabase()方法计时:如果第一次做大量工作(例如打开数据库文件!)然后缓存它所做的事情,那么您将因此产生很多开销。尝试在时区之前单独调用该方法,这样您就知道开销不会太小。

其次,SQLite 的工作原理是将 SQL 编译成内部字节码形式,然后在自己的小型虚拟机中执行。编译步骤可能有不小的成本,并且特定于 SQL 和查询的表。幸运的是,您每次都发送相同的 SQL(这是一个常量表名,是吗?)并且 SQLite 足够聪明,可以实现编译的 LRU 缓存,因此如果您两次运行相同的查询,它会更快。(我不知道缓存的大小;它可能是在您构建 SQLite 时设置的,具有一些合理的默认值。)理论上您可以通过每次查询不同的表来测试这一点,但这很愚蠢。关闭与数据库的连接也将摆脱此缓存,但会保证您获得较差的性能;你'

第三,SQLite 很可能只在实际需要时才读取有关数据库及其表的一些信息,所以如果这是对该表的第一次查询,您可能会承担一些额外的费用。尝试在计时运行之前先对表进行不同的(否则从未使用过)查询。(另外,请注意我在上一段中的警告。)

第四,ORM 层可能正在缓存结果,但坦率地说,这实际上不太可能,因为这很难正确处理(困难的部分是由于数据库正在更新,何时刷新查询结果缓存,实际上更容易只是不打扰这种复杂性)。

于 2013-07-17T08:23:04.670 回答
0

第一次调用 SQL 语句时,SQLite 引擎必须准备该类型化的 SQL 语句,即将人类可读的文本转换为机器可执行代码,这会带来少许开销。

于 2013-07-17T07:58:58.367 回答