Sto lavorando a una funzione di ricerca in una delle mie app basate sui dati principali e sto cercando di raccogliere tutti i suggerimenti sull'ottimizzazione della ricerca per ottenerla il più velocemente possibile. La ricerca deve essere abbastanza veloce da fornire risultati quasi istantanei per un database di oltre 20.000 oggetti.Ottimizzazione della ricerca dei dati principali
Quello che ho fatto finora (per quanto riguarda l'ottimizzazione va)
- implementato la tecnica mostrata nella WWDC 2010 sessione di 137, la creazione di un'entità parola chiave e la creazione di un rapporto a-molti dei miei principali entità oggetto ad esso. L'attributo dell'entità parola chiave
name
è indicizzato, e le parole chiave vengono creati durante la procedura iniziale di importazione, dividendo le stringhe a parte rilevanti nei soggetti principali e normalizzare (spogliato di cassa e segni diacritici) - Utilizzando
>=
e<
comparatori binari invece diBEGINSWITH
, ecc . il mio formato predicato è:
SUBQUERY(keywords, $keyword, ($keyword.name >= $LB) AND ($keyword.name < $UB))[email protected] != 0
Dove $LB
è la stringa limiti inferiore e $UB
è limiti superiori. Creo un predicato composto AND
utilizzando questo formato e l'array di termini di ricerca.
In questo momento, sto eseguendo un'operazione di recupero una volta (quando l'utente digita la prima lettera) utilizzando una dimensione di recupero lotto di circa 20, e quindi restringendo i risultati di ricerca utilizzando il metodo di -filteredArrayUsingPredicate NSArray mentre continuano a digitare. Predispongo anche alla relazione keywords
perché viene utilizzata per filtrare. La parte che occupa più tempo, ovviamente, è il recupero iniziale. C'è un notevole ritardo di ~ 1-2 secondi su una libreria di circa 15.000 oggetti. profiling tempo dimostra che è in effetti l'operazione di recupero che sta causando il ritardo:
http://cl.ly/3a1b2022452M2V323f2H
Un altra cosa questo è degni di nota è che devo andare a prendere più entità per i risultati. Tutte le entità hanno un attributo ranking
, ma non riesco a recuperarne più di una in una volta, quindi sono costretto a recuperarle separatamente, combinarle in un unico array e quindi ordinare manualmente tramite -sortedArrayUsingDescriptors
.
Tutti i suggerimenti su come accelerare questo sarebbe molto apprezzato.
EDIT: Sulla base di suggerimenti @ImHuntingWabbits':
Dopo l'aggiunta di un'entità KeywordFirstChar
, il mio modello di dati (semplificato) sarebbe simile a questa:
Ora, le domande è come scrivere un predicato per l'entità Car
basata su KeywordFirstChar
? L'unica cosa che mi viene in mente sarebbe questo:
SUBQUERY(keywords, $keyword, $keyword.firstChar.char == %@)
dove %@
è il carattere da cercare, ma non so come questo sarebbe molto più efficace se si considera che ha ancora enumerare oltre keywords
, a meno che non erroneamente interpretato i suggerimenti.
Non stai iterando su ogni parola chiave, l'SQL generato dovrebbe solo controllare il valore del char nella tabella keywordFirstChar. Il set di risultati delle entità Car verrà recuperato eseguendo un join da KeywordFirstChar a Keyword per Car. – ImHuntingWabbits
Sì, capito. Funziona molto meglio ora, molto più velocemente. Grazie – indragie