Re: Core Data: different fetch performance when launching app [SOLVED]
Re: Core Data: different fetch performance when launching app [SOLVED]
- Subject: Re: Core Data: different fetch performance when launching app [SOLVED]
- From: Diederik Hoogenboom <email@hidden>
- Date: Sat, 14 Oct 2006 15:45:18 +0200
Jakob,
Thanks! Your last remark did the trick. I just added parentItem ==
nil to the predicate of the arraycontroller and the fetch now take
0.156 seconds the first time.
I would have expected that Z_ENT would be indexed. It's one of the
primary columns that are always there. Is there a way to add an index
to a table in the SQLLite store, other then creating an relationship?
Kind regards,
Diederik
On 14-okt-2006, at 13:26, Jakob Olesen wrote:
On 14/10/2006, at 9.36, Diederik Hoogenboom wrote:
Total records in the store is about 30,000. There are
relationships as well. Everything is bound to an arraycontroller
and treecontroller. The entity StorageItem it is querying is the
superclass of all the entities.
StorageItem has a tree structure; it point to itself via a
relationship called 'items'. There is also an inverse called
parentItem. There is a subclass of StorageItem called Catalog
which objects are the top objects of the trees (and have some
additional properties). When the app starts it displays
(NSTableView for the Catalog objects and NSOutlineView for the
related (items relationship) StorageItem objects). It should only
query all Catalog objects (about 10 records) and the first level
of the StorageItems (about 12 records), right? It doesn't have to
go through the whole object graph I guess.
When you create an entity inheritance hierarchy, Core Data merges
the data for subentities into the root entity table, so in your
case all your entity instances are in the same table. The Z_ENT
attribute is like the isa pointer, it identifies the entity type.
Your SQL query for the Catalog items is essentially this:
SELECT * FROM ZSTORAGEITEM S WHERE S.Z_ENT = ? ORDER BY S.ZNAME
There is no index on Z_ENT, so SQLite has to do a full table scan
to find the Catalog instances. It has to look at all 30,000
records, and so it needs to read all the blocks of your database
file, even if it only returns 10 records. There is a good chance it
won't be reading the blocks sequentially, and that can be really
slow when they are not cached yet.
Once the blocks are cached (by both the kernel and SQLite
internally) a full table scan of 1.5MB is not a big issue.
There are several ways you can speed up your initial query:
1. Break up your inheritance hierarchy, so you get more tables. If
your Catalog instances are in a smaller table, you get them faster.
2. Use a relationship to fetch the Catalog instances. Relationships
are indexed, so you avoid the full table scan.
3. Force the kernel to cache your database file by reading it
sequentially before the fetch.
If your Catalog instances are tree roots with a null parentItem,
try using that in your fetch predicate: "parentItem=nil". Since
parentItem is a relationship, it is indexed, and you avoid the full
table scan. That is the simplest solution (if it works...)
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden