Optimiza el rendimiento de las consultas
Para solucionar problemas de consultas lentas, usa Explicación de consulta para obtener el plan de ejecución de consultas y el perfil de ejecución del tiempo de ejecución. En la siguiente sección, se describen los pasos que puedes seguir para optimizar el rendimiento de las consultas según el perfil de ejecución:
Limita la cantidad de resultados
Usa el campo records returned en el árbol de ejecución para
identificar si la consulta devuelve muchos documentos. Considera limitar la cantidad
de documentos que se devuelven con la
etapa limit(...). Esto reduce el tamaño de los bytes serializados de los resultados cuando
se devuelven a los clientes a través de la red. En los casos
en que el nodo Limit está precedido por un nodo MajorSort, el motor de consultas puede
fusionar los nodos Limit y MajorSort, y reemplazar una materialización y una ordenación completas en la memoria
por una ordenación TopN, lo que reduce el requisito de memoria para
la consulta.
Limita el tamaño del documento de resultado
Considera limitar el tamaño del
documento que se devuelve con un select(...) para devolver solo los campos
requeridos o remove_fields(...) para descartar los campos
demasiado grandes. Esto ayuda a reducir el costo de procesamiento y memoria
de los resultados intermedios, y el tamaño de bytes serializados de los resultados cuando se devuelven
a los clientes a través de la red. En los casos en que todos los campos a los
que se hace referencia en la consulta están cubiertos por un índice normal, esto también permite que
la consulta esté completamente cubierta por el análisis del índice, lo que evita la necesidad de recuperar documentos del
almacenamiento principal.
Usa índices
Sigue estas instrucciones para configurar y optimizar los índices.
Identifica si la consulta usa un índice
Para identificar si la consulta usa un índice, verifica los nodos hoja en el árbol de ejecución. Si el nodo hoja de ejecución es un nodo TableScan, significa que la consulta no usa un índice y está analizando documentos del almacenamiento principal. Si se usa un índice, el nodo hoja de ejecución mostrará el ID y los campos del índice.
Identifica un mejor índice
Un índice es útil para una búsqueda si puede reducir la cantidad de documentos que el motor de búsqueda necesita recuperar del almacenamiento principal o si el orden de sus campos puede satisfacer el requisito de ordenamiento de la búsqueda.
Si se usa un índice para una consulta, pero el motor de consultas sigue recuperando y descartando muchos documentos, como lo identifica un nodo de análisis que devuelve muchos registros seguido de un nodo de filtro que devuelve pocos registros, esto es un signo de que el predicado de la consulta que se cumple con el índice no es selectivo. Para crear un índice más adecuado, consulta Crea índices.
Si se usa un índice para una consulta, pero el motor de consultas sigue realizando una reordenación en la memoria del conjunto de resultados, como se identifica con un nodo MajorSort en el árbol de ejecución de la consulta, esto indica que el índice utilizado no se puede usar para cumplir con el requisito de ordenamiento de la consulta. Para crear un índice más adecuado, consulta la siguiente sección.
Crea índices
Sigue la documentación de administración de índices para crear índices. Para asegurarte de que tu consulta pueda usar índices, crea índices regulares (no de varias claves) con campos en el siguiente orden:
- Son todos los campos que se usarán en los operadores de igualdad. Para maximizar la probabilidad de reutilización en las consultas, ordena los campos en orden descendente de la frecuencia con la que aparecen en los operadores de igualdad entre las consultas.
- Todos los campos por los que se ordenará (en el mismo orden).
- Campos que se usarán en operadores de rango o desigualdad en orden descendente de selectividad de la restricción de consulta.
- Campos que se devolverán como parte de una consulta en el índice: Incluir estos campos en el índice permite que este cubra la consulta y evita tener que recuperar el documento del almacenamiento principal.
Forzar un análisis de índice o tabla
Cuando consultas Firestore en modo nativo, se usan automáticamente los índices que probablemente hagan que la consulta sea más eficiente. Como resultado, no es necesario que especifiques un índice para tus consultas. Sin embargo, para las consultas que son críticas para tu carga de trabajo, te recomendamos que uses la opción forceIndex para obtener un rendimiento más coherente.
Sin embargo, en algunos casos, Firestore en modo nativo podría elegir un índice que aumente la latencia de las consultas. Si seguiste los pasos para solucionar problemas de regresiones de rendimiento y confirmaste que tiene sentido probar otro índice para la consulta, puedes especificar el índice con la opción forceIndex.
Puedes usar la opción forceIndex en cualquier etapa de entrada de las operaciones de canalización para anular el plan de consultas predeterminado de Firestore en modo nativo y especificar un índice para usar, o bien forzar un análisis de tabla.
Cómo forzar un índice específico
Para forzar la consulta a usar un índice específico, proporciona el ID del índice como una cadena a la opción forceIndex. Puedes encontrar el ID del índice en la consola o en los mensajes de error.
En el siguiente ejemplo, se obliga al planificador a usar el índice con el ID CICAgOi36pgK:
// Force Planner to use Index ID CICAgOi36pgK
db.pipeline()
.collectionGroup({ collectionId: "customers", forceIndex: "CICAgOi36pgK" })
.limit(100)
Estos son algunos casos de uso para forzar un índice específico:
- Probar el rendimiento de diferentes índices
- Garantizar que se use un índice específico y óptimo conocido para una consulta
- Anular el optimizador cuando su elección predeterminada no es óptima para una consulta en particular
Si no se encuentra el índice especificado, la consulta falla.
Forzar un análisis de tabla
Un análisis de tabla lee documentos en la colección o el grupo de colecciones sin usar ningún índice secundario. Para forzar un análisis de tabla, configura forceIndex como primary.
En el siguiente ejemplo, se fuerza un análisis de tabla:
// Force Planner to only do a Full-Table Scan
db.pipeline()
.collectionGroup({ collectionId: "customers", forceIndex: "primary" })
.limit(100)
Puedes usar un análisis de tabla en los siguientes casos:
- Para colecciones muy pequeñas en las que no se justifica la sobrecarga del índice.
- Para las búsquedas que acceden a la mayoría de los documentos de una colección.
- Para la depuración y las comparaciones de rendimiento
Usa forceIndex con Query Explain
Puedes usar Query Explain, en especial con la opción analyze, para observar los efectos de forceIndex:
- Verifica que Firestore en modo nativo haya usado el índice especificado en
forceIndex. Para ello, revisa los nodos hoja del árbol de ejecución en busca del ID del índice. - Confirma que aparezca un nodo
TableScanen el plan cuando usesforceIndex: "primary". - Compara las métricas de rendimiento (como la latencia, los documentos analizados y las entradas de índice analizadas) con y sin
forceIndexpara ajustar el rendimiento de las consultas.
Prácticas recomendadas para forceIndex
Si bien forceIndex proporciona más control sobre la ejecución de consultas, el optimizador de consultas de Firestore en modo nativo suele ser eficiente para la mayoría de los casos de uso.
Ten en cuenta las siguientes prácticas recomendadas cuando uses forceIndex:
- Usa
forceIndexcon buen juicio. Si observas un rendimiento no óptimo con el plan de consultas predeterminado, usa Explicación de consulta para diagnosticar el problema antes de forzar un índice. - Cuando uses
forceIndex, asegúrate de probar tus consultas con volúmenes de datos realistas para comprender sus características de rendimiento y costo. - Evita usar
forceIndex: "primary"en colecciones grandes en entornos de producción.