8

If my Author NSManagedObject model has a authorID attribute (determined by the server), will an NSFetchRequest perform better if the NSPredicate filters by authorID rather than the complete Author object? Let's say I'm fetching all Book NSManagedObjects by a certain author. Which predicateFormat is better?

[NSPredicate predicateWithFormat:@"author = %@", anAuthor]

or

[NSPredicate predicateWithFormat:@"author.authorID = %@", anAuthor.authorID]

What's the best way to profile this? I have Core Data testing working with OCUnit (SenTestingKit). Does iOS have something like Ruby's Benchmark module?

ma11hew28
  • 121,420
  • 116
  • 450
  • 651
  • Do you have the author object at hand when performing the fetch? If you were to use the Author object, I am assuming you'd need to first fetch it and then perform a second request for the books by that author (2 trips to the database). If you already have the id you can get the results you need with one fetch request. – Rog Dec 22 '11 at 23:17
  • This won't solve your issue but you better know that Apple Documentation states that you should use '==' and not just '=' when writing predicates. – Fabiano Francesconi Jul 12 '12 at 10:44

2 Answers2

1

It might be worth running your app with an argument of -com.apple.CoreData.SQLDebug 1, as detailed here.

You could then see if Core Data was executing the same SQL in both circumstances (assuming you're using a SQLite store).

paulbailey
  • 5,328
  • 22
  • 35
0

The first one (using just Author) would probably be faster, but only testing will tell you for sure.

If you fetch (e.g. Book) objects that have an relationship to Author and you use a predicate

[NSPredicate predicateWithFormat:@"author = %@", anAuthor]

SQLite can see if the merge table from Book to Author has the right primary key for that given author. In other words, the predicate turns into a check for the Author entities primary key. CoreData still has to consult the merge table, though.

If you use

[NSPredicate predicateWithFormat:@"author.authorID = %@", anAuthor.authorID]

then SQLite will have to join the merge table with the actual Author table and then match the resulting authorID column. That would be more work. And it would break down if authorID isn't indexed.

Daniel Eggert
  • 6,665
  • 2
  • 25
  • 41
  • I came across this while debugging a similar predicate; I'm not able to get an object based predicate to work, using the same format you have in the first example. Inspecting the data directly in sqlite confirms that it isn't working. I'd like to know more, or understand why it may not be working – wkhatch Jan 13 '12 at 10:14
  • What does the SQL request look like? What kind of inspecting are you doing? – Daniel Eggert Jan 13 '12 at 20:45