2009-09-26 3 views
3

En fait, je travaille sur une application iPhone Core Data. J'ai deux entités qui contiennent plus de 200 000 lignes chacune et je rencontre des problèmes de performances lors de la récupération des données. Pour chaque requête d'extraction, je dois attendre entre 1 et 2 secondes avant d'obtenir des résultats. Je pense mettre en œuvre un moteur de recherche personnalisé pour indexer mes données mais le problème est que toute la base de données est éditable. Le contenu peut être modifié à tout moment, donc indexer une base de données de contenu dynamique est stupide. Je me demande si les données de base sont suffisamment efficaces pour fournir une recherche instantanée. Dans la documentation Apple, une entité de mille lignes est considérée comme petite. Est-ce correct?Les données de base sont-elles plus efficaces que l'indexation personnalisée pour la recherche de type "as-you-type"?

Quelqu'un at-il une solution pour améliorer la vitesse des données de base ...? Ou devrais-je implémenter mon propre moteur de recherche?

Le but est de fournir une recherche instantanée, une recherche pendant que vous tapez le mécanisme.

[UPDATE] est Ci-dessous un extrait de l'un de mes chercher demande ...

NSString *predicateString = [NSString stringWithFormat:@"^(.*\\b)?%@(\\b.*)?$", searchString]; 
NSString *predicate = [NSString stringWithString:@"text MATCHES[cd] %@"]; 
NSArray *arguments = [NSArray arrayWithObjects:predicateString, nil]; 

NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease]; 
[fetchRequest setEntity:[NSEntityDescription entityForName:@"MyEntity" inManagedObjectContext:[[HYDataManager instance] managedObjectContext]]]; 
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:predicate argumentArray:arguments]]; 
[fetchRequest setSortDescriptors:[NSArray arrayWithObjects:[[NSSortDescriptor alloc] initWithKey:@"length" ascending:YES], [[NSSortDescriptor alloc] initWithKey:@"subEntity.attr1" ascending:YES], [[NSSortDescriptor alloc] initWithKey:@"subEntity.attr2" ascending:YES], nil]]; 
[fetchRequest setResultType:NSDictionaryResultType]; 
[fetchRequest setReturnsDistinctResults:YES]; 
[fetchRequest setPropertiesToFetch:[NSArray arrayWithObject:@"subEntity"]]; 

NSFetchedResultsController *controller = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[[HYDataManager instance] managedObjectContext] sectionNameKeyPath:nil acheName:nil]; 
+0

Êtes-vous aller chercher plus que nécessaire? Je jetterai un coup d'oeil à votre requête de recherche et ne retournerai que le strict minimum dont vous avez besoin pour afficher ce qui est à l'écran. Regardez setPropertiesToFetch: sur le NSFetchRequest pour voir si vous pourriez être en mesure de le réduire un peu. Assurez-vous également que vos modèles sont correctement indexés. – Hunter

+0

S'il vous plaît montrer votre demande de récupération - de légères différences dans la façon dont vous effectuez le fetch peuvent faire une grande différence dans les performances. –

+0

Vous pouvez regarder ma demande de récupération ci-dessus! –

Répondre

2

Vous pouvez essayer plusieurs choses.

1) essayez d'utiliser setFetchBatchSize: pour réduire le jeu de données de travail dans votre application. En combinaison avec un NSFetchedResultsController, ceci va fausser les lots à la demande de manière transparente, en montrant les objets sur votre table si nécessaire. 2) vérifiez si vous pouvez utiliser setResultType: avec NSManagedObjectIDResultType. Cela retournera seulement l'ID des objets correspondants; Si vous n'avez besoin d'accéder qu'à un ou plusieurs d'entre eux après l'exécution de la requête d'extraction, le surcoût supplémentaire est vraiment faible, mais l'extraction est beaucoup plus rapide. Si vous avez besoin d'accéder à tous les objets retournés, alors ce n'est pas le chemin à parcourir.

3) si vous avez besoin au lieu de récupérer les propriétés stockées dans vos objets, utilisez setPropertiesToFetch: comme suggéré par Hunter pour récupérer seulement ceux que vous avez vraiment besoin

4) si votre modèle comprend des sous-entités de votre entité, vérifiez si vous pouvez utiliser setIncludesSubentities: en passant NO comme argument.

5) si vous n'avez pas besoin de traiter tous les objets correspondant au prédicat associé à votre requête d'extraction, utilisez setFetchLimit: pour récupérer un nombre fixe d'objets.

Espérons que cela aide.

0

Avez-vous essayé de marquer tous les éléments modifiables indexés dans le modèle de données? Comme vous l'avez dit, il semble vraiment étrange de tout indexer, mais les données de base devraient être assez intelligentes pour gérer cela de manière appropriée.

Questions connexes