Rendimiento MySQL campos calculados

eXtreM3

Holis,
tengo una pregunta. ¿A partir de qué momento empieza a ser rentable crear un campo calculado en una base de datos?
Me explico: pongamos que tenemos dos tablas, MANZANAS y MANZANAS_VENDIDAS.

En MANZANAS guardamos datos típicos: idManzana, color, peso...
En MANZANAS_VENDIDAS guardamos datos por cada venta: idManzana, timestamp venta, vendedor...

Para saber las manzanas vendidas, manteniendo la relación entre ambas tablas, tengo que recorrer tooodas las filas de MANZANAS_VENDIDAS (con sus joins, where, etc.) para obtener el resultado.

Sin embargo, si guardo en la tabla MANZANAS un campo "vendidas", la consulta es instantánea. Pero estaremos creando un poquito de redundancia.

Pues eso, ¿cuándo sí y cuándo no hacer esta práctica?

B
#1eXtreM3:

En MANZANAS_VENDIDAS

No tienes algún campo que determine la cantidad de esa venta?

RaymaN

A partir de que el rendimiento sin calcular se vea comprometido, habiendo intentado antes optimizar la configuración de mysql y los índices y estructura de la consulta.

Aún así, yo soy partidario de implementar antes una cache con redis o similar en el backend. Añadir campos calculados puede ser una fuente de inconsistencia importante, y más si son datos críticos.

1 3 respuestas
MTX_Anubis

Pues como casi todo en el software, depende de tus métricas, no de lo que te vayamos a decir xD

Por lo demás estoy bastante con #3.

Beavis

Como ya te han dicho todo depende de la carga de la base de datos y de la aplicación. Si la consulta es un cuello de botella saltarse la la normalización y crear datos redundantes es algo muy normal, pero claro conlleva un aumento de la complejidad del código de la aplicación para garantizar la consistencia de los datos (depende de lo críticos que sean puedes ser más o menos estricto con eso).
El tema de la caché en otra capa pues depende del uso, si es un campo que vas a usar para ordenar una tabla por ejemplo es mucho más efectivo tenerlo redundante e indexado en la tabla principal de la bd para poder hacer la consulta directamente sin filesorts ni temp tables y sin tener que recurrir a cachés externas (que van a tener la misma complejidad para mantener la consistencia)

Merkury

Pero #3 como vas a mantener una metrica como es el computo total en una cache volatil?

#1 yo creo que un campo calculado en Manzanas puede hacer el truco, siempre y cuando lo mantengas perfectamente sincronizado, porque si hay una devolucion o tal tendras que descontarlo y guardar otra metrica no?

La cosa es que calcularlo al vuelo por mucho indice que tengas va a costar bastante...

2 respuestas
MTX_Anubis

#6 Hombre, entiendo que #3 se refiere por un lado a tener cacheado ese dato y por otro tener las relaciones persistidas de donde poder sacar los datos xD

1 respuesta
willy_chaos

No se el caso pero por ejemplo podrias hacer que mediante trigger (asi no has de tocar codigo de la app) se haga el +1 o -1 ( o +n) a ese campo.

Por ejemplo si cada noche quiero sacar un reporte de lo vendido, pero tambien quiero poder verlo en tiempo real por el dia. Para el horario del dia haria caso al campo del trigger sabiendo que puede no ser real del todo (aunque deberia ser consistente) y para el reporte nocturno me patearia la tabla (ya que solo lo haces 1 vez)

RaymaN

#6 es como dice #7, las relaciones son las mismas, solo guardas el dato calculado con un expire de minutos/horas. La opción del trigger también es buena, yo la uso para datos críticos que necesitan estar sincronizados pero que no sean de constante actualización, de lo contrario estarías añadiendo un insert/update para ahorrarte un join xD

willy_chaos

Obviamente en la solucion que te digo es por cada id de producto y con un campo con la fecha del dia.

Una vez generas ese reporte como habras tenido que sumar las cantidades vendidas, aprovechas y actualizas el campo del trigger y asi ya tienes 100% consistencia)

eXtreM3

La consistencia no es problema, para eso están las transacciones y/o los triggers. La cosa es que implementar una caché externa para esto no lo veo, sobre todo si es para recuperar datos de ventas a tiempo real.

Soltrac

Saltarse la normalización es algo que no se hace en la teoría y sí en la práctica. Es completamente lógico.

Hoy en día en bases de datos relacionales, con transacciones es muy difícil corromper la consistencia, salvo que se dañe la base de datos, pero bueno, en ese caso es cuestión de recalcular.

Lo normal es usar triggers como te han dicho por arriba y si necesitas hacerlo por código, usar transacciones.

Usuarios habituales

  • Soltrac
  • eXtreM3
  • willy_chaos
  • RaymaN
  • MTX_Anubis
  • Merkury
  • Beavis