2010-04-09 4 views
0

Je reçois des prix moyens par semaine sur 7 millions de lignes, cela prend environ 30 secondes pour faire le travail.Calculer la moyenne (AVG) et grouper par semaine sur un grand ensemble de données prend trop de temps

Ceci est la recherche simple:

SELECT AVG(price) as price, yearWEEK(FROM_UNIXTIME(timelog)) as week from pricehistory where timelog > $range and product_id = $id GROUP BY week 

La semaine seulement qui obtient effectivement des données a changé et est une valeur moyenne à chaque fois est toujours la dernière, donc ce calcul pour toute la période est un gaspillage de ressources. Je voulais juste savoir si mysql a un outil pour aider à ça.

Répondre

1

Avez-vous essayé d'indexer les champs?

Je ne suis pas un expert DDL en MySQL, mais dans ce cas, je dirais que timelog devrait avoir un index cluster, alors les index non cluster devraient être déclarés pour product_id. Aussi, ce serait une bonne idée d'ajouter un nouveau champ à la table, pour stocker la valeur "week" et l'indexer aussi. Il faudrait un peu plus d'espace, mais de cette façon, vous éviterez de faire les mêmes calculs à chaque fois.

+0

En MySQL clustered ne peut être que la clé primaire, principalement dans les tables InnoBD. – newtover

+0

hummm. Je suis sur myisam –

1

Je suggère la création d'un nouvel indice composite BTREE sur (product_id, TimeLOG) et changer l'ordre des conditions dans la clause WHERE:

SELECT 
    AVG(price) as price, 
    yearWEEK(FROM_UNIXTIME(timelog)) as week 
from pricehistory 
where product_id = $id AND timelog > $range 
GROUP BY week 

Si vous avez déjà un indice de BTREE sur (product_id) seulement, juste étendez-le à (product_id, timelog)

+0

J'ai essayé cette approche sans amélioration significative. Une requête impliquant toutes les 7 millions de lignes prend 40-45 à compléter. –

+0

Les requêtes impliquant moins de données sont cependant plus rapides. Laisse-moi le tester un peu plus. –

Questions connexes