Tengo una tabla con alrededor de 20 millones de filas. Por razones de argumentos, digamos que hay dos columnas en la tabla: una identificación y una marca de tiempo. Estoy tratando de contar el número de artículos por día. Esto es lo que tengo en este momento.Agilizando una consulta de grupo por fecha en una gran mesa en postgres
SELECT DATE(timestamp) AS day, COUNT(*)
FROM actions
WHERE DATE(timestamp) >= '20100101'
AND DATE(timestamp) < '20110101'
GROUP BY day;
Sin ningún índice, esto toma alrededor de 30 segundos para funcionar en mi máquina. Aquí está la salida explicar analizar:
GroupAggregate (cost=675462.78..676813.42 rows=46532 width=8) (actual time=24467.404..32417.643 rows=346 loops=1)
-> Sort (cost=675462.78..675680.34 rows=87021 width=8) (actual time=24466.730..29071.438 rows=17321121 loops=1)
Sort Key: (date("timestamp"))
Sort Method: external merge Disk: 372496kB
-> Seq Scan on actions (cost=0.00..667133.11 rows=87021 width=8) (actual time=1.981..12368.186 rows=17321121 loops=1)
Filter: ((date("timestamp") >= '2010-01-01'::date) AND (date("timestamp") < '2011-01-01'::date))
Total runtime: 32447.762 ms
Desde que estoy viendo un recorrido secuencial, he tratado de índice en la fecha agregada
CREATE INDEX ON actions (DATE(timestamp));
que corta la velocidad en un 50%.
HashAggregate (cost=796710.64..796716.19 rows=370 width=8) (actual time=17038.503..17038.590 rows=346 loops=1)
-> Seq Scan on actions (cost=0.00..710202.27 rows=17301674 width=8) (actual time=1.745..12080.877 rows=17321121 loops=1)
Filter: ((date("timestamp") >= '2010-01-01'::date) AND (date("timestamp") < '2011-01-01'::date))
Total runtime: 17038.663 ms
Soy nuevo en este negocio de optimización de consultas, y no tengo ni idea de qué hacer a continuación. ¿Alguna pista de cómo puedo hacer que esta consulta se ejecute más rápido?
--edit--
Parece que estoy golpeando los límites de los índices. Esta es prácticamente la única consulta que se ejecuta en esta tabla (aunque los valores de las fechas cambian). ¿Hay alguna forma de particionar la tabla? ¿O crear una tabla de caché con todos los valores de conteo? O alguna otra opción?
¿Nos está contando toda la historia aquí? Parece que ha cambiado la configuración de memoria entre el primero y el segundo plan. Cuál habría sido mi consejo. ;-) –
Sin cambios en la configuración de la memoria, aunque he estado haciendo un análisis de vacío entre cada cambio de esquema. No sé si se supone que debo hacer eso, pero sí afecta seriamente los resultados. – zaius