Tag: 移动数据库

移动数据库优化:领域与SQLite

在这个故事中,我将告诉您我们如何开发结构化方法来解决复杂的技术问题,并成功地将应用程序的性能提高了30倍。 我们开始收集具有技术要求的新企业应用程序的开发。 最初,我们发现我们的应用程序应包含以下主要功能: 包含图表的报告 一个简单的任务跟踪系统 公司全体员工名单 所有这些数据也应可供脱机使用。 听起来不太难,对吧? 我们是这样认为的。 我们基于JSON进行了客户端与服务器之间的交互,并基于SQLite进行了脱机数据在移动设备上的存储,从而获得了最初的技术堆栈。 在iOS上,我们使用了几年前非常流行的CoreData包装器MagicalRecord。 今天,这绝对是一个错误的选择,因为它是用Objective-C编写的,并且在过去3年中没有任何更新。 但是,在2014年,它是免费的,开源的,并且在GitHub上拥有1万颗星,但是主要原因是缺少其他选择。 在Android上,出于相同的原因,我们决定使用ORMLite。 在开发过程的早期,一切都很好。 我们的开发服务器上有一些演示报告和数十名员工。 但是,在将产品卖给第一个客户之后,我们就遇到了严重的性能问题。 后端团队的同事将客户生产数据库的一部分导入了我们的测试环境。 而且我们发现我们的应用尚未准备好与20万名员工一起使用。 下载完整列表花费了5到10分钟,滚动性能很差,搜索根本不起作用。 这不是我们最终用户所期望的。 另一个问题是报告。 其中一些包含具有数百万个点的图表,因此我们遇到了同样的问题:两个平台上的下载速度缓慢且性能不佳。 我们试图进行一些修复,将分页引入客户端-服务器请求并将批处理写入本地数据库,但是我们无法将性能提高得足够高。 对我们来说幸运的是,我们的销售部门与客户签订了长达6个月的合同,第一部分是更新一些内部系统,因此我们需要一两个月的时间来解决问题。 我们了解到,我们需要对发生的问题进行全面研究,而不是编写混乱的错误修复程序。 下面我将详细介绍我们的方法。 这项研究 我们从优化员工名单绩效开始。 经过几次快速修复错误的失败尝试之后,我们决定将下载员工列表并将其显示在UI中的过程分成较小的步骤,并测量每个步骤的持续时间,以找出需要解决的问题。 最后,我们发现等待服务器响应(30秒)并写入本地数据库(5-10m)是整个过程中最长的两个部分,而其他部分仅花费了几百毫秒,因此不需要注意。 服务器响应 在进行任何优化之前,我们只需要下载一次完整的员工列表即可。 之所以选择这种方法,是因为此列表的任何一部分对最终用户都没有任何价值。 没有人希望看到姓氏以字母A开头的员工。我们的用户需要完整的列表才能访问所有联系人并执行离线搜索。 我们还具有喜欢的联系人功能,可通过我们的服务器在用户设备之间进行同步。 首先,我们将喜欢的数据移动到本地数据库中的单独请求和单独表中。 那并没有给我们带来巨大的性能提升,而是让我们在服务器端启用完整员工列表的内存存储。 响应时间优化的最后也是最重要的部分是引入增量更新。 如上所述,我们在服务器端将完整的员工列表存储在内存中。 它将响应时间从大约30秒减少到仅1-2秒,由于网络延迟,我们无法再将其缩短。 与后端和销售团队讨论了我们的解决方案之后,我们还发现员工名单通常每天仅可以更新一次,因此无需进行更频繁的更新。 因此,为了减少服务器端的负担并加快移动客户端上的数据库写入速度,我们引入了增量更新。 首次安装后,我们的应用程序立即下载完整列表,但第二天它要求服务器进行一次小的增量更新,以提供最新数据应用程序的版本(时间戳)。 本地数据库优化 增量更新极大地减少了员工列表更新时间。 但是,我们仍然有两个问题: 由于SQLite的写入速度,初始加载太慢 由于完全相同的原因,应用少量增量更新(例如,在两周不活动之后)也花费了很多时间 在批量编写没有提高性能之后,我们决定尝试其他方法。 我们有一个假设,在我们的案例中,SQLite或MagicalRecord都是瓶颈。 因此,我们提出了两种可能的解决方案: 切换ORM 与其他数据库切换SQLite 我们没有找到MagicalRecord的替代品,因此决定使用CoreData。 […]