Featured post
iphone - fetch request performance issues -
i have serious performance issues when querying sqlite database approx. 25k rows. want following: user types textfield want give him autocompletition suggestions in tableview inputaccessoryview of keyboard. each time enters new character, 4 new queries go off search appropriate suggestions. in seperate thread using gcd , blocks. performance low. here's code 1 query:
- (void) querydatabase:(nsstring *) searchstring { [self.fetchedresults removeallobjects]; dispatch_queue_t fetchqueue = dispatch_queue_create("fetch queue", null); dispatch_async(fetchqueue,^{ nserror *error = nil; nsmanagedobjectcontext *context = [[nsmanagedobjectcontext alloc] init]; context.undomanager = nil; [context setpersistentstorecoordinator: self.persistentstorecoordinator]; nspredicate *predicate = [nspredicate predicatewithformat:@"reducedtownname %@", [searchstring stringbyappendingstring:@"*"]]; nsfetchrequest *request = [[nsfetchrequest alloc] init]; request.entity = [nsentitydescription entityforname:@"station" inmanagedobjectcontext:context]; request.fetchlimit = 20; [request setincludespropertyvalues:no]; request.predicate = predicate; request.resulttype = nsmanagedobjectidresulttype; nsarray *results = [context executefetchrequest:request error:&error]; nsenumerator *e = [results objectenumerator]; nsmanagedobjectid *objectid = nil; while (objectid = [e nextobject]) { station *station = (station *) [self.managedobjectcontext objectwithid:objectid]; if ( ![self.fetchedresults containsobject:station]) [self.fetchedresults addobject:station]; } dispatch_async(dispatch_get_main_queue(),^{ [self.tableview reloaddata]; }); [request release]; [context release]; }); //do 3 more queries similar first (only predicate changes) dispatch_release(fetchqueue); }
i use nsarray (fetchedresults) hold returned entities , update tableview data array.
does see performance killer in code, or has other advice me?
i think might have spotted it.
you query entities , put results array. that's query number 1 , it's optimized ok (assuming there no joins etc doesn't there are)
then, go through results remove duplicates in results. means execute new query each station nsmanagedobject. if want avoid duplicates have without calling objectwithid
because et object coredata.
worst case, 20 stations results, need 21 queries. not good.
as sqlite3 single threaded, why don't make large predicate instead of 4 smaller ones - can remove duplicates in predicate , won't need go through array until it's time draw station's table view cell.
i've had problem before lookups , had solve making seperate table in database. in case table (called station_search) contain station name (which indexed of course) , stationid. searches on table (which fast because it's not got lots of data search through).
once i've got results use stationid station main stations table only when need it i.e. i'm drawing cell in table.
i can use nsfetchedresultscontroller batch results together.
this has turned bit of ramble - if have questions ask!
hope helps,
sam
- Get link
- X
- Other Apps
Comments
Post a Comment