核心数据在iPhone上的表现绝对是悲惨的.索引是完全破坏还是只是一个糟糕的实现?
我的核心数据存储(SQLite后备存储)中有大约21500个单一类型的对象.对象在UUID上索引,UUID是NSString(例如,一个看起来像这样:"6b09e200-07b6-11df-a245-002500a30d78").
使用NSManagedObjectContext中的executeFetchRequest对象存在的单个提取大约需要0.75秒!这是最简单的谓词"uuid == $ UUID",其中$ UUID是一个类似上面例子的字符串.
这真的很令人惊讶.如果我想逐个获取商店中的每个对象,则需要将近4.5小时!
反正有没有改善这种性能,还是我应该放弃核心数据?
小智 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的东西
如果它缺少"带索引"那么你在创建核心数据存储的方式上有一些问题(你确定模型被标记为索引uuid吗?)或者你的获取请求还有其他的东西.
这真的很令人惊讶.如果我想逐个获取商店中的每个对象,它将需要将近4.5个小时!
我想你可以这样做,作为最痛苦的方式之一.或者您可以使用-setFetchBatchSize:并快速迭代批量对象.
另外,请记住,每次提取都会对数据库执行I/O操作,以保持与其他任何线程保存的内容同步.提取不是一些神奇的字典查找.执行最小的I/O单元所需的时间有一个下限.您将要分摊单个I/O请求的数量以获得最佳性能.你必须平衡这一点,而不是一次读入太多内存.
如果您仍然遇到问题,请向bugreport.apple.com提交错误
这不会回答你的问题,但可能会给你一些思考的机会。在 iPhone 上只使用 SQLite 我对性能感到非常失望。我正在处理大约 8000 个条目,如果返回全部等等,则需要大约两分钟的时间来插入/排序。
通过使用它,我发现在内存中过滤/排序所需的时间比 SQLite 完成的时间要好 100 倍,我认为这主要是由于闪存的性能。
简而言之,核心数据使用闪存的次数越少,您将获得更好的性能,并且我认为没有很多方法可以使其变得更好。
| 归档时间: |
|
| 查看次数: |
6775 次 |
| 最近记录: |