2012-02-15 51 views
1

我有一个SQLite数据库,在表中只有超过6000行地址。这是一个只读数据库 - 在应用程序构建和部署完成后没有任何更新或更改。我有一个关于州领域的索引。我的应用程序使用简单的select语句来获取与给定状态相匹配的所有行。我使用了explain和explain查询计划语句来查看我的查询正在使用索引。Android变量SQLite选择查询性能 - 任何解释?

大多数情况下,查询在一秒钟内回来 - 不是很好,但足以满足我的应用程序的需求。

每隔一段时间查询都需要更长的时间 - 甚至高达14秒,通常是3-4秒。在完全相同的只读数据库(和表)上完全相同的查询在同一个手机上,由完全相同的二进制调用。

我可以看到没有垃圾收集发生,并正在从监控logcat的

不会产生异常有只是有时会发生变化。造成不一致用户体验的变体。

似乎SQLite数据库系统正在被其他应用程序共享 - 比如电子邮件客户端。难道我的查询是在另一个应用程序的查询之后排队的,因此这种变化是由于共享SQLite数据库系统实际上运行我的查询的时间?如果是这种情况,是否可以“创建我自己的SQLite实例”,以便获得一致的性能?

如果它不是一个共享的SQLite数据库系统(因此我有自己的实例),在其他所有条件都相同的情况下,还有什么可能导致查询性能发生如此大的变化?

请注意,我不能轻松地将数据带入内存中,因为行很长(有更多信息而不仅仅是地址),并且我有一些其他部分代码可以使用更复杂的选择查询。我将性能差异缩小到了这个问题最简单的“select where state =”查询(请求帮助)。

回答

3

似乎SQLite数据库系统正在被其他应用程序共享 - 比如电子邮件客户端。

不完全是。 存储被其他应用程序共享。在Android 1.x和大多数2.x设备上,内部存储的格式为YAFFS2,一次只允许一个进程访问存储。对于运行ext4而不是YAFFS2的Android 3.0+设备(以及一些2.3设备),这应该不是什么问题。

难道是我的查询排队在另一个应用程序的查询之后,因此这种变化是由于共享SQLite数据库系统实际上运行我的查询的时间?

不完全是。不过,您的磁盘I/O可能会排在其他应用程序的磁盘I/O之后。

+0

这可能是它。数据库应该被复制到外部存储器,但我认为它是私有的外部存储器,它可能是格式化的YAFFS2(我需要检查),因此也有同样的问题。数据库在未压缩的情况下被复制到外部存储器(8MB压缩到20MB未压缩)以最小化分发.apk文件大小。 – Colin 2012-02-15 20:02:00

+0

@Colin:我认为私人外部存储只是FAT32/vfat分区(Android 1.x/2.x)上的一个目录。我不知道在1.x/2上同时访问外部存储的细节。x,但是。 – CommonsWare 2012-02-15 20:10:57