En esta página, se describen los conceptos que debes tener en cuenta a la hora de seleccionar índices de Firestore en modo Datastore para tu app.
Firestore en modo Datastore ofrece un alto rendimiento de consultas mediante el uso de índices para todas las consultas. El rendimiento de la mayoría de las consultas depende del tamaño del conjunto de resultados y no del tamaño total de la base de datos.
Firestore en modo Datastore define los índices integrados para cada propiedad de una entidad. Estos índices de propiedad única admiten muchas consultas simples. Firestore en modo Datastore admite una función de combinación de índices que permite que tu base de datos combine índices integrados para admitir consultas adicionales. Para consultas más complejas, debes definir índices compuestos con anticipación.
Esta página se centra en la función de combinación de índices, ya que afecta dos oportunidades importantes de optimización de índices:
- Aceleración de las consultas
- Reducir la cantidad de índices compuestos
En el siguiente ejemplo, se muestra la función de combinación de índices.
Filtra entidades Photo
Considera una base de datos de modo Datastore con entidades del tipo Photo
:
Foto | ||
---|---|---|
Propiedad | Tipo de valor | Descripción |
owner_id |
String | ID de usuario |
tag |
Arreglo de strings | Palabras clave con asignación de token |
size |
Número entero | Enumeración:
|
coloration |
Número entero | Enumeración:
|
Imagina que necesitas una función de app que permita a los usuarios consultar entidades Photo
según una lógica AND
de lo siguiente:
Hasta tres filtros basados en las propiedades:
owner_id
size
coloration
Una string de búsqueda de
tag
. La aplicación asigna un token a la string de búsqueda con etiquetas y agrega un filtro para cada etiqueta.Por ejemplo, la app convierte la string de búsqueda
outside, family
en los filtros de consultatag=outside
ytag=family
.
Puedes cumplir con los requisitos de índice de esta función de filtro Photo
sin agregar índices compuestos adicionales mediante los índices integrados y la función de combinación de índices de Firestore en modo Datastore.
Los índices integrados para las entidades Photo
admiten consultas de filtro único, como las siguientes:
Python
La función de filtro Photo
también requiere consultas que combinen varios filtros de igualdad con un AND
lógico:
Python
Firestore en modo Datastore puede admitir estas consultas mediante la combinación de índices integrados.
Combinación de índices
Firestore en modo Datastore puede usar la combinación de índices cuando la consulta y los índices cumplan con todas las siguientes restricciones:
- La consulta solo usa filtros de igualdad (
=
). - No existe un índice compuesto que coincida a la perfección con los filtros y el orden de la consulta.
- Cada filtro de igualdad coincide con al menos un índice existente con el mismo orden que la consulta.
En esta situación, Firestore en modo Datastore puede usar índices existentes para admitir la consulta en lugar de requerir que configures un índice compuesto adicional.
Cuando se ordenan dos o más índices según los mismos criterios, Firestore en modo Datastore puede combinar los resultados de varios análisis de índices para encontrar los resultados que son comunes a todos esos índices. Firestore en modo Datastore puede combinar los índices integrados, ya que todos ordenan los valores por clave de entidad.
Mediante la combinación de los índices integrados, Firestore en modo Datastore admite consultas con filtros de igualdad en varias propiedades:
Python
Firestore en modo Datastore también puede combinar los resultados de índice de varias secciones del mismo índice. Mediante la combinación de diferentes secciones del índice integrado para la propiedad tag
, Firestore en modo Datastore admite consultas que combinan varios filtros tag
en un AND
lógico:
Python
Las consultas admitidas por los índices integrados combinados completan el conjunto de consultas que requiere la función de filtro Photo
. Ten en cuenta que, para admitir la función de filtro Photo
, no se necesitaban índices compuestos adicionales.
Cuando selecciones los índices óptimos para tu app, es importante que comprendas la función de combinación de índices. La combinación de índices le brinda a Firestore en modo Datastore una mayor flexibilidad de consulta, pero podría afectar el rendimiento. En la siguiente sección, se describe el rendimiento de la combinación de índices y cómo mejorarlo mediante la incorporación de índices compuestos.
Cómo encontrar el índice perfecto
El índice se ordena primero por entidad principal y, luego, por valor de las propiedades, en el orden especificado en la definición del índice. El índice compuesto perfecto de una consulta, que permite que esta se ejecute de la manera más eficiente, se define según las siguientes propiedades y en este orden:
- Propiedades usadas en filtros de igualdad
- Propiedades usadas en órdenes de clasificación
- Propiedades usadas en el filtro
distinctOn
- Propiedades usadas en el rango y filtros de desigualdad (que aún no están incluidos en los órdenes de clasificación)
- Propiedades usadas en agregaciones y proyecciones (que aún no se incluyen en las órdenes de clasificación ni en los filtros de rango y desigualdad)
Esto garantiza que se registren todos los resultados para cada ejecución posible de la consulta. Las bases de datos de Firestore en modo Datastore ejecutan una consulta con un índice perfecto mediante los siguientes pasos:
- Identifica el índice correspondiente a la categoría, las propiedades de filtro, los operadores de filtro y el ordenamiento de la consulta.
- Busca desde el principio del índice hasta la primera entidad que cumple con todas las condiciones de filtro de la consulta o un subconjunto de ellas.
- Continúa la búsqueda del índice y muestra cada entidad que satisfaga todas las condiciones del filtro hasta que se cumpla alguna de las siguientes condiciones:
- Encuentra una entidad que no cumple con las condiciones del filtro.
- Se alcanza el final del índice.
- Se recopiló la cantidad máxima de resultados solicitados por la consulta.
Por ejemplo, considera la siguiente consulta:
SELECT * FROM Task
WHERE category = 'Personal'
AND priority < 3
ORDER BY priority DESC
El índice compuesto perfecto para esta consulta es un índice de claves para entidades de tipo Task
, con columnas para los valores de las propiedades category
y priority
. El índice se ordena primero en orden ascendente por category
y, luego, en orden descendente por priority
:
indexes:
- kind: Task
properties:
- name: category
direction: asc
- name: priority
direction: desc
Dos consultas del mismo formato, pero con valores de filtro diferentes, usan el mismo índice. Por ejemplo, la siguiente consulta usa el mismo índice que la consulta anterior:
SELECT * FROM Task
WHERE category = 'Work'
AND priority < 5
ORDER BY priority DESC
Considera este índice:
indexes:
- kind: Task
properties:
- name: category
direction: asc
- name: priority
direction: asc
- name: created
direction: asc
El índice anterior puede satisfacer ambas consultas:
SELECT * FROM Task
WHERE category = 'Personal'
AND priority = 5
ORDER BY created ASC
y
SELECT * FROM Task
WHERE category = 'Work'
ORDER BY priority ASC, created ASC
Optimiza la selección de índices
En esta sección, se describen las características de rendimiento de la combinación de índices y dos oportunidades de optimización relacionadas:
- Agrega índices compuestos para agilizar las consultas que dependen de índices combinados.
- Reduce la cantidad de índices compuestos mediante el uso de índices combinados
Rendimiento de la combinación de índices
En una combinación de índices, Firestore en modo Datastore combina los índices de manera eficiente mediante un algoritmo de combinación en zigzag. Con este algoritmo, el modo Datastore une las posibles coincidencias de varios análisis de índices para producir un conjunto de resultados que coincida con una consulta. La combinación de índices combina los componentes del filtro en el momento de la lectura en lugar de la escritura. A diferencia de la mayoría de las consultas de Firestore en modo Datastore, en las que el rendimiento depende solo del tamaño del conjunto de resultados, el rendimiento de las consultas de combinación de índices depende de los filtros de la consulta y de la cantidad de coincidencias potenciales que considera la base de datos.
El mejor rendimiento posible de la combinación de índices ocurre cuando todas las coincidencias potenciales en un índice satisfacen los filtros de consulta. En este caso, el rendimiento es O(R * I)
. R
es el tamaño del conjunto de resultados, mientras que I
es el número de índices analizados.
El peor rendimiento posible ocurre cuando la base de datos debe considerar muchas coincidencias potenciales, pero pocas satisfacen los filtros de la consulta. En este caso, el rendimiento es O(S)
. S
es el tamaño del conjunto más pequeño de entidades potenciales de un análisis de índices único.
El rendimiento real depende de la forma de los datos. El número promedio de entidades consideradas para cada resultado que se muestra es O(S/(R * I))
. Las consultas tienen un peor rendimiento cuando muchas entidades coinciden con cada análisis de índice, pero pocas entidades coinciden con la consulta en general, lo que significa que R
es pequeño y S
es grande.
Hay cuatro factores que mitigan este riesgo:
El planificador de consultas no busca una entidad hasta que sabe que la entidad coincide con toda la consulta.
El algoritmo de zigzag no necesita encontrar todos los resultados para mostrar el siguiente resultado. Si solicitas los primeros 10 resultados, solo pagarás la latencia por encontrar esos 10 resultados.
El algoritmo de zigzag omite grandes secciones de resultados que son falsos positivos. El peor rendimiento posible ocurre solo si los resultados que son falsos positivos están bien entrelazados (en orden de clasificación) entre los análisis.
La latencia depende de la cantidad de entidades que se encuentran en cada análisis de índices, no de la cantidad de entidades que coinciden con cada filtro. Como se muestra en la siguiente sección, puedes agregar índices compuestos para mejorar el rendimiento de la combinación de índices.
Acelera una consulta de combinación de índices
Cuando Firestore en modo Datastore combina índices, cada análisis de índices a menudo se asigna a un solo filtro en la consulta. Para mejorar el rendimiento de las consultas, agrega índices compuestos que coincidan con varios filtros en la consulta.
Considera esta consulta:
Python
Cada filtro se asigna a un análisis de índice en los siguientes índices integrados:
Index(Photo, owner_id) Index(Photo, size) Index(Photo, tag)
Si agregas el índice compuesto Index(Photo, owner_id, size)
, la consulta asigna dos análisis de índices en lugar de tres:
# Satisfies both 'owner_id=username' and 'size=2'
Index(Photo, owner_id, size)
Index(Photo, tag)
Considera una situación con muchas imágenes grandes, muchas imágenes en blanco y negro, pero pocas imágenes panorámicas grandes. Un filtro de consulta para imágenes panorámicas y en blanco y negro será lento si combina índices integrados:
Python
A fin de mejorar el rendimiento de las consultas, puedes reducir el valor de S
(el conjunto más pequeño de entidades en un análisis de índices único) en O(S/(R * I))
si agregas el siguiente índice compuesto:
Index(Photo, size, coloration)
En comparación con el uso de dos índices integrados, este índice compuesto produce menos resultados potenciales para los mismos dos filtros de consulta. Este enfoque mejora de forma sustancial el rendimiento a costa de un índice más.
Reduce la cantidad de índices compuestos con la combinación de índices
Aunque los índices compuestos que tienen una concordancia exacta con los filtros de una consulta tienen un mejor rendimiento, no siempre es mejor o posible agregar un índice compuesto para cada combinación de filtros. Debes equilibrar tus índices compuestos con los siguientes elementos:
Límites de índices compuestos:
Límite Importe Cantidad máxima de índices compuestos que se permiten para una base de datos -
200 cuando no habilitaste la facturación para tu proyecto de Google Cloud.
Si necesitas aumentar la cuota, debes habilitar la facturación para tu proyecto de Google Cloud.
-
500 cuando habilites la facturación para tu proyecto de Google Cloud.
Puedes comunicarte con el equipo de asistencia para solicitar un aumento de este límite.
Suma máxima de los tamaños de las entradas en el índice compuesto de una entidad 2 MiB Suma máxima de lo siguiente para una entidad: - la cantidad de valores de propiedad indexados
- la cantidad de entradas en el índice compuesto
20,000 -
- Los costos de almacenamiento de cada índice adicional
- Efectos sobre la latencia de escritura
Suelen surgir problemas de indexación con campos de varios valores, como la propiedad tag
de las entidades Photo
.
Por ejemplo, imagina que la función de filtro Photo
ahora debe admitir cláusulas de orden descendente basadas en cuatro propiedades adicionales:
Foto | ||
---|---|---|
Propiedad | Tipo de valor | Descripción |
date_added |
Número entero | Fecha y hora |
rating |
Número de punto flotante | Calificación agregada de los usuarios |
comment_count |
Número entero | Cantidad de comentarios |
download_count |
Número entero | Cantidad de descargas |
Si ignoras el campo tag
, es posible seleccionar índices compuestos que coincidan con cada combinación de filtros Photo
:
Index(Photo, owner_id, -date_added) Index(Photo, owner_id, -comments) Index(Photo, size, -date_added) Index(Photo, size, -comments) ... Index(Photo, owner_id, size, -date_added) Index(Photo, owner_id, size, -comments) ... Index(Photo, owner_id, size, coloration, -date_added) Index(Photo, owner_id, size, coloration, -comments)
La cantidad total de índices compuestos es la siguiente:
2^(number of filters) * (number of different orders) = 2 ^ 3 * 4 = 32 composite indexes
Si intentas admitir hasta 3 filtros tag
, la cantidad total de índices compuestos es la siguiente:
2 ^ (3 + 3 tag filters) * 4 = 256 indexes.
Los índices que incluyen propiedades de varios valores, como tag
, también generan problemas de índices con alto crecimiento, que aumentan los costos de almacenamiento y la latencia de escritura.
A fin de admitir filtros en el campo tag
para esta función, puedes reducir la cantidad total de índices si usas índices combinados. El siguiente conjunto de índices compuestos es el mínimo necesario para admitir la función de filtro Photo
con un orden:
Index(Photo, owner_id, -date_added) Index(Photo, owner_id, -rating) Index(Photo, owner_id, -comments) Index(Photo, owner_id, -downloads) Index(Photo, size, -date_added) Index(Photo, size, -rating) Index(Photo, size, -comments) Index(Photo, size, -downloads) ... Index(Photo, tag, -date_added) Index(Photo, tag, -rating) Index(Photo, tag, -comments) Index(Photo, tag, -downloads)
La cantidad de índices compuestos definidos es la siguiente:
(number of filters + 1) * (number of orders) = 7 * 4 = 28
La combinación de índices también proporciona los siguientes beneficios:
- Permite que una entidad
Photo
admita hasta 1,000 etiquetas sin límite en la cantidad de filtrostag
por consulta. - Reduce la cantidad total de índices, lo que disminuye los costos de almacenamiento y la latencia de escritura.
Selecciona índices para tu app
Puedes seleccionar índices óptimos para tu base de datos en modo Datastore mediante dos enfoques:
La combinación de índices para admitir consultas adicionales tiene las siguientes características:
- Requiere menos índices compuestos.
- Reduce el costo de almacenamiento por entidad.
- Mejora la latencia de escritura
- Evita los índices con alto crecimiento.
- El rendimiento depende de la forma de los datos.
Definir un índice compuesto que coincida con varios filtros en una consulta
- Mejora el rendimiento de las consultas.
- Genera un rendimiento de consultas coherente que no depende de la forma de los datos.
- Debe permanecer por debajo del límite de índices compuestos.
- Hay un mayor costo de almacenamiento por entidad.
- Hay una mayor latencia de escritura
Cuando buscas los índices óptimos para la app, la respuesta puede cambiar a medida que lo hace la forma de los datos. El rendimiento de las consultas de muestra te brinda una idea acertada de las consultas comunes de la app y las consultas lentas. Con esta información, puedes agregar índices para mejorar el rendimiento de las consultas comunes y lentas.