I’ve got what should be a pretty simple CoreData setup that looks like this:
Track {
NSSet *artists;
NSSet *genres;
}
Artist {
NSSet *tracks;
}
Genre {
NSSet *tracks;
}
So the idea here is, a Track can have multiple Genres and Artists. There is an inverse relationship back to Track in both cases.
I’m trying to get a list of Artists which have at least one Track of a given Genre. I’m using the following predicate: [NSPredicate predicateWithFormat:@"ANY tracks in %@", genre.tracks].
Most of the time this is fast, but sometimes I have a Genre with 10k+ Tracks. This generates a SQL query with 10k+ variables… this takes a long time to run.
I’ve tried all kinds of things to avoid this including:
[NSPredicate predicateWithFormat:@"ANY %@ in tracks", genre.tracks]
[NSPredicate predicateWithFormat:@"SELF IN SUBQUERY(tracks, $t, %@ IN $t.genres)", genre]
[NSPredicate predicateWithFormat:@"(SUBQUERY(tracks, $t, %@ IN $t.genres).@count > 0)", genre];
And probably some more that I’ve forgotten. Each of these compiles, but returns no Artist objects.
What can I do to improve upon the efficiency of the IN query I started with (which works)?
You can use
which gives the same result as your original predicate, but avoids to build a query with many parameters.