Estoy trabajando en una función de búsqueda en una de mis aplicaciones basadas en datos centrales y estoy tratando de reunir los consejos de todos sobre la optimización de búsqueda para obtenerla lo más rápido posible. La búsqueda debe ser lo suficientemente rápida como para proporcionar resultados casi instantáneos para la base de datos de más de 20,000 objetos.Optimización de búsqueda de datos principales
Lo que he hecho hasta ahora (en lo que va de optimización)
- implementó la técnica mostrada en la WWDC 2010 Sesión 137, la creación de una entidad de palabras clave y crear una relación a muchos de mis principales entidades de objetos lo. atributo de la entidad palabra clave
name
está indexado, y las palabras clave son creados durante el procedimiento inicial de importación mediante el fraccionamiento de cadenas separadas relevantes en las entidades principales y la normalización de ellos (despojado de caso y signos diacríticos) - Usando
>=
y<
comparadores binarios en lugar deBEGINSWITH
etc . Mi formato predicado es:
SUBQUERY(keywords, $keyword, ($keyword.name >= $LB) AND ($keyword.name < $UB))[email protected] != 0
Dónde $LB
es la cadena de límites inferior y es $UB
límites superiores. Creo un predicado compuesto AND
usando este formato y la matriz de términos de búsqueda.
En este momento estoy ejecutando una búsqueda (cuando el usuario escribe la primera letra) utilizando un tamaño de lote de búsqueda de aproximadamente 20, y luego reduciendo los resultados de búsqueda utilizando el método NSArray -filteredArrayUsingPredicate mientras continúan escribiendo. También prefetch la relación keywords
porque esto se usa para filtrar. La parte que ocupa más tiempo, obviamente, es la búsqueda inicial. Hay una notable demora de ~ 1-2s en una biblioteca de alrededor de 15,000 objetos. perfiles de tiempo muestra que es de hecho la zona de alcance que está causando el retraso:
http://cl.ly/3a1b2022452M2V323f2H
otro eso es cosa que cabe destacar es que tengo que ir a buscar múltiples entidades de los resultados. Todas las entidades tienen un atributo ranking
, pero no puedo buscar más de una a la vez, así que me veo obligado a buscarlas por separado, combinarlas en una única matriz y luego ordenarlas manualmente a través del -sortedArrayUsingDescriptors
.
Cualquier consejo sobre cómo acelerar esto sería muy apreciado.
EDIT: Sobre la base de las sugerencias @ImHuntingWabbits':
Después de agregar una entidad KeywordFirstChar
, mi modelo de datos (simplificado) podría tener este aspecto:
Ahora, la pregunta es ¿cómo escribiría un predicado para la entidad Car
que recupera según KeywordFirstChar
? Lo único que se me ocurre sería la siguiente:
SUBQUERY(keywords, $keyword, $keyword.firstChar.char == %@)
donde %@
es el carácter a buscar, pero no saben cómo esto sería mucho más eficiente teniendo en cuenta que todavía tiene que enumerar más de keywords
, a menos que yo malinterpretó las sugerencias.
No está iterando sobre cada palabra clave, el SQL generado solo debería verificar el valor char en la tabla keywordFirstChar. El conjunto de resultados de las entidades de Auto se buscará haciendo una combinación desde KeywordFirstChar a Keyword to Car. – ImHuntingWabbits
Sí, lo tengo. Funciona mucho mejor ahora, mucho más rápido. Gracias – indragie