如何提高iPhone上的核心数据获取性能?

时间:2010-08-27 21:42:35

标签: iphone core-data

核心数据在iPhone上的表现绝对是悲惨的。索引是完全破坏还是只是一个糟糕的实现?

我的核心数据存储(SQLite后备存储)中有大约21500个单一类型的对象。对象在UUID上建立索引,这是一个NSString(例如,一个看起来像这样:“6b09e200-07b6-11df-a245-002500a30d78”)。

使用NSManagedObjectContext中的executeFetchRequest进行对象存在的单次提取大约需要0.75秒!这是最简单的谓词“uuid == $ UUID”,其中$ UUID是一个类似上面例子的字符串。

这真的很令人惊讶。如果我想逐个获取商店中的每个对象,则需要将近4.5个小时!

无论如何都要改善这种性能,还是应该一起放弃核心数据?

4 个答案:

答案 0 :(得分:10)

几点。如果需要5秒钟才能获取21,500行,这听起来就像是在旧设备上运行。像3G或原始iPhone。这些内存和I / O性能非常慢。您需要非常谨慎地处理数据,以避免将其全部读入内存并进行不必要的I / O.您可能会发现-setFetchBatchSize特别有用。如果你在3GS上运行,可管理10-20万行,但需要小心。如果您使用的是ipad或iphone4,这应该不是什么大问题。

除了与外部系统(如服务器)连接外,您不需要创建自己的UUID。每个受管对象都有一个objectID,它是其主键的OOP表示。只需传递objectID,然后执行@“self =%@”或@“self IN%@”等查询,按ID或ID数组搜索对象。您还可以使用-existingObjectWithID:error:仅通过其objectID查找1个对象,这将比使用通用谓词的通用提取请求更快。

验证索引的最佳方法正如您所期望的那样使用可执行参数在模拟器中运行应用程序

-com.apple.CoreData.SQLDebug 1

将记录控制台生成的SQL。你应该看到一些东西以t0.uuid ==?

结尾

您可以使用该SQL select语句,并通过SQLite的explain查询工具运行它。对模拟器中的db文件运行/ usr / bin / sqlite3。做

  

.explain ON   解释查询计划copythatsqllinehere

它应该打印出像这样的东西 0 | 0 |表ZFOO as t0 with INDEX something

如果它缺少“带索引”,那么你在创建Core Data存储的方式上有一些问题(你确定模型被标记为索引uuid吗?)或者你的获取请求还有其他东西。

  

这真的很令人惊讶。如果我想逐个获取商店中的每个对象,那么>将需要将近4.5个小时!

我想你可以这样做,作为最痛苦的方式之一。或者您可以使用-setFetchBatchSize:并快速迭代批量对象。

另外,请记住,每次提取都会对数据库执行I / O操作,以保持与其他任何线程保存的内容同步。提取不是一些神奇的字典查找。执行最小的I / O单元所需的时间有一个下限。您将要分摊单个I / O请求的数量以获得最佳性能。你必须要平衡这一点,不要一次读入太多内存。

如果您仍然遇到问题,请向bugreport.apple.com提交错误

答案 1 :(得分:2)

这不会回答你的问题,但可能会给你一些思考。在iPhone上使用SQLite我对性能感到非常失望。我正在处理大约8000个条目,如果全部返回则需要大约两分钟插入/排序等等。

玩弄它我发现在内存中过滤/排序所需的时间比让它完成SQLite好100倍,我认为这主要是由于闪存的性能。

简而言之,Core Data必须使用更少的闪存才能获得更好的性能,而且我认为没有太多方法可以让它变得更好。

答案 2 :(得分:2)

我认为问题是比较字符串要比大多数(如果不是全部数据库)的数字慢得多。

您可以尝试为NSManagedObject添加一个新属性(列),aNumber,这是一个数字,并从其UUID生成值。

然后,构建您的查询,例如“aNumber == XXX AND uuid == UUID”

这可以使数据库首先比较一个数字,如果数字相同,它只需要比较一个字符串。

或者,您可以尝试索引UUID。

答案 3 :(得分:1)

使用核心数据的技巧是,只有实际需要的数据才能从存储中获取并保存在内存中。我无法想象如何在像iPhone这样的设备上编辑/重新排序/任何21500行。 有几种方法可以提高CoreData的性能: - setFetchBatchSize - 使用原始方法 - 仅加载所需的属性

我记得比较SQLite&的WWDC视频CoreData性能和CD是一个明显的赢家。