Sqlite 核心数据:使用谓词获取项目的速度很慢

Sqlite 核心数据:使用谓词获取项目的速度很慢,sqlite,core-data,nsfetchrequest,Sqlite,Core Data,Nsfetchrequest,对于我的iPhone应用程序,我为核心数据建立了一个数据模型。它包含一个实体Words,其属性为language:String、length:Integer16和word:String 我在模型的SQLite数据库中预先填充了一个单词列表(200k个条目),使用相同的数据模型编写了一个单独的iPhone应用程序,并将填充的数据库添加到主应用程序中 现在使用NSFetchedRequest,我可以随意查询托管对象,但结果很慢。我使用以下方法: - (NSString *)getRandomWord

对于我的iPhone应用程序,我为核心数据建立了一个数据模型。它包含一个实体
Words
,其属性为
language:String
length:Integer16
word:String

我在模型的SQLite数据库中预先填充了一个单词列表(200k个条目),使用相同的数据模型编写了一个单独的iPhone应用程序,并将填充的数据库添加到主应用程序中

现在使用NSFetchedRequest,我可以随意查询托管对象,但结果很慢。我使用以下方法:

- (NSString *)getRandomWordLengthMin:(int)minLength max:(int)maxLength
{
    NSString *word = @"";

    MyAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    NSManagedObjectContext *context = [appDelegate managedObjectContext];    
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Words"
                                              inManagedObjectContext:context];
    [fetchRequest setEntity:entity];

    NSString *predicateString = @"length >= %d AND length <= %d";
    NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateString,
                              minLength, maxLength];
    [fetchRequest setPredicate:predicate];

    NSError *error = nil;
    int entityCount = [context countForFetchRequest:fetchRequest error:&error];
    [fetchRequest setFetchLimit:1];
    if(entityCount != 0)
    {
        [fetchRequest setFetchOffset:arc4random()%entityCount];
    }

    NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
    if([fetchedObjects count] != 0)
    {
        Words * test = [fetchedObjects objectAtIndex:0];
        word = [NSString stringWithFormat:@"%@", [test word]];
    }

    return word;
}

不要使用SQLite编辑器为核心数据存储编辑SQLite备份存储。数据库的内部是私有的,可能会发生更改

而是转到Xcode中的模型编辑器,只需在要索引的实体属性的“indexed”选项上打一个复选标记

不确定,但可能此谓词更容易优化:

NSString *predicateString = @"length BETWEEN (%d, %d)";

不要使用SQLite编辑器为核心数据存储编辑SQLite备份存储。数据库的内部是私有的,可能会发生更改

而是转到Xcode中的模型编辑器,只需在要索引的实体属性的“indexed”选项上打一个复选标记

不确定,但可能此谓词更容易优化:

NSString *predicateString = @"length BETWEEN (%d, %d)";

这里实际上运行了两次抓取,一次获取抓取计数,然后一次获取实际对象。那会让事情变慢的


您的谓词是“向后”的。复合谓词计算第一个表达式,例如
长度>=%d
,然后计算第二个表达式,例如
长度您在这里有效地运行了两次获取,一次获取获取计数,然后一次获取实际对象。那会让事情变慢的


您的谓词是“向后的”。复合谓词计算第一个表达式,例如
长度>=%d
,然后计算第二个表达式,例如
长度似乎不可能在
之间。另请参见。似乎不可能在
之间执行
。另请参见。谢谢,现在我只获取一个提前确定了固定长度的属性(最小值/最大值显著降低了速度)。谢谢,现在我只获取一个提前确定了固定长度的属性(最小值/最大值显著降低了速度)。