Algunas sugerencias.
Probablemente va a ejecutar consultas agregadas sobre estas cosas, por lo que después (o mientras) cargue los datos en sus tablas, debe preagregar los datos, por ejemplo, calcular totales por hora, o por usuario, o por semana, lo que sea, obtiene la idea, y la almacena en tablas de caché que usa para sus gráficos de informes. Si puede reducir su conjunto de datos en un orden de magnitud, entonces, ¡bien por usted!
Esto significa que obtendré algunos datos en un intervalo utilizando marcas de tiempo.
¿Esto significa que solo utiliza los datos de los últimos X días?
Eliminar los datos antiguos de las tablas puede ser terriblemente lento si tiene que eliminar algunas decenas de millones de filas, el particionamiento es ideal (simplemente suelte esa partición anterior). También agrupa todos los registros del mismo período de tiempo juntos en el disco para que sea mucho más eficiente en la caché.
Ahora, si utiliza MySQL, le sugiero que use tablas MyISAM. No obtienes protección contra fallas o transacciones y el bloqueo es tonto, pero el tamaño de la tabla es mucho menor que InnoDB, lo que significa que puede caber en la memoria RAM, lo que significa un acceso mucho más rápido.
Dado que los grandes agregados pueden implicar una gran cantidad de IO en disco secuencial, un sistema IO rápido como RAID10 (o SSD) es un plus.
¿Hay alguna forma de optimizar la tabla o consulta para que pueda realizar estas consultas en un tiempo razonable?
Eso depende de la tabla y las consultas; no puedo dar ningún consejo sin saber más.
Si necesita consultas complicadas de informes con grandes agregados y uniones, recuerde que MySQL no admite ningún JOINs sofisticado, o agregados hash, o cualquier otra cosa realmente útil, básicamente, lo único que puede hacer es indexado de bucle anidado que es bueno en una tabla en caché, y absolutamente atroz en otros casos si se trata de un acceso aleatorio.
Sugiero que pruebe con Postgres. Para grandes agregados, el optimizador más inteligente funciona bien.
Ejemplo:
CREATE TABLE t (id INTEGER PRIMARY KEY AUTO_INCREMENT, category INT NOT NULL, counter INT NOT NULL) ENGINE=MyISAM;
INSERT INTO t (category, counter) SELECT n%10, n&255 FROM serie;
(Serie contiene líneas 16M con n = 1 .. 16000000)
MySQL Postgres
58 s 100s INSERT
75s 51s CREATE INDEX on (category,id) (useless)
9.3s 5s SELECT category, sum(counter) FROM t GROUP BY category;
1.7s 0.5s SELECT category, sum(counter) FROM t WHERE id>15000000 GROUP BY category;
en una consulta simple como este PG es aproximadamente 2-3 veces más rápido (la diferencia sería ser mucho más grande si se trata de uniones complejas).