gpt4 book ai didi

iphone - 带有 BOOL 检查的 NSFetchRequest 谓词很慢

转载 作者:行者123 更新时间:2023-12-03 18:45:08 25 4
gpt4 key购买 nike

考虑通过 5k+ 条目存储过滤以下 2 个谓词:

predicate1 = [NSPredicate predicateWithFormat:@"hidden == NO AND name BEGINSWITH[cd] %@", searchString];
predicate2 = [NSPredicate predicateWithFormat:@"name BEGINSWITH[cd] %@", searchString];

我打开-com.apple.CoreData.SQLDebug来查看获取请求时间:

谓词1:0.4728s
谓词2:0.0867s

我错过了什么吗?两列均已建立索引。为什么添加一个简单的 bool 检查会大大减慢获取请求的速度?

编辑:根据要求,输出:

CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZHIDDEN, t0.ZID, t0.ZNAME, t0.ZRANK FROM ZARTISTINDEX t0 WHERE ( t0.ZHIDDEN = ? AND ( NSCoreDataStringSearch( t0.ZNAME, ?, 393, 0) OR  NSCoreDataStringSearch( t0.ZNAME, ?, 393, 0))) ORDER BY t0.ZRANK DESC LIMIT 14

rank列也已建立索引。我需要这个请求快于 0.5 秒的原因是它用于自动完成功能。每次用户更改某个文本字段的值时都会发出该请求。

编辑 2:添加更多上下文信息:

- (NSArray*)autocompleteSuggestions:(NSString*)searchString {

NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"ArtistIndex" inManagedObjectContext:self.indexObjectContext];
[request setEntity:entity];
[request setFetchLimit:10];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"hidden == NO AND (name BEGINSWITH[cd] %@ OR name BEGINSWITH[cd] %@)", searchString, [NSString stringWithFormat:@"the %@", searchString]];
[request setPredicate:predicate];

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"rank" ascending:NO];
[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];

NSArray *resultsArray = [self.indexObjectContext executeFetchRequest:request error:nil];
[request release];

return resultsArray;
}

ArtistIndex 实体具有以下属性:

  • id(int32)
  • 名称(字符串,已索引)
  • 排名(int32,已索引)
  • 隐藏(BOOL,已索引)

编辑 3:以下是 slow query (predicate1) 的完整 SQL 输出和 fast query (predicate2)将 com.apple.CoreData.SQLDebug 设置为 3。更严格的测试为我带来了以下测试时间,这些时间更好,但仍然有 2 倍的差异,并且在自动完成建议上下文中确实产生了影响。或者现在这是一个合理的获取时间差异吗?

谓词1:0.3772s
谓词2:0.1633s

最佳答案

对于 2 列的 where 子句和仅 1 列的索引,sqlite 可能决定在 bool 字段上使用索引。这会导致快速选择,但会在内部导致加载一半的数据集;然后它开始执行另一个子句,但它需要通过查看每条记录来做到这一点。这就是 bool 搜索导致速度减慢的原因。

我认为您应该尝试 3 种方法。

  1. 除非两列上都有一个索引,否则对 2 列的查询性能会很差。我不相信 Core Data 允许您在单个索引中索引多个列,但底层 SQLite 数据库可以。因此,为了查看这是否是导致问题的原因,请尝试在 SQLite 数据库的两列上手动创建索引。重要的是,您的 bool 值是索引中的第二列,因为它不够独特(它只有 2 个值,因此需要过滤的数据集是数据库的一半;这使得索引效率稍低)。

  2. 添加一个实用程序列,其中包含名称和隐藏字段的串联,并对其进行索引和搜索。但这可能不太有效,因为您正在匹配子字符串。

  3. 如果hidden=YES的记录数量较少,则将其排除在谓词之外,然后再进行过滤。

关于iphone - 带有 BOOL 检查的 NSFetchRequest 谓词很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6689260/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com