2010-02-20 11 views
4

J'archive ce forum web, qui est normalement purgé environ une fois par semaine. Je suis donc en train de le scrapper et de le stocker dans ma base de données (PostgreSQL). Je fais aussi un peu d'analyse sur les données, avec quelques graphiques pour les utilisateurs, comme l'heure de la journée est le forum le plus actif, et ainsi de suite.Requête SQL terriblement lente avec COUNT et GROUP BY sur deux colonnes

J'ai une table de messages, comme ceci:

Column |   Type 
------------+------------------------------ 
id   | integer 
body  | text 
created_at | timestamp without time zone 
topic_id | integer 
user_name | text 
user_id | integer 

Et je veux maintenant avoir un compteur de messages pour chaque utilisateur, pour ma petite table top 10 des affiches.

je suis venu avec ceci:

SELECT user_id, user_name, count(*) 
FROM posts 
GROUP BY user_id, user_name 
ORDER BY count DESC LIMIT 10 

qui se révèle être très lente. 9 secondes, avec à peine 300 000 lignes dans la table des messages pour le moment.

Cela ne prend qu'une demi-seconde, si je grouper sur une seule colonne, mais j'ai besoin des deux.

Je suis plutôt nouveau pour les bases de données relationnelles, et SQL, donc je ne suis pas tout à fait sûr si c'est juste, ou juste comment je le fais mal?

Répondre

11

Il n'y a probablement qu'un seul utilisateur avec un ID particulier, donc max(user_name) doit être égal à user_name. Ensuite, vous pouvez groupe sur une seule colonne, que votre poste indique fonctionne plus rapidement:

SELECT user_id, max(user_name), count(*) 
FROM posts 
GROUP BY user_id 
+0

+1 yup, qui est la façon de le faire:). Dans la spécification sql 1999 et plus, il est réellement permis de lister des colonnes non agrégées dans la liste 'SELECT' qui n'apparaissent pas dans la liste' GROUP BY', tant que ces colonnes dépendent fonctionnellement du 'GROUP BY 'liste. Bougie éhontée: http://rpbouman.blogspot.com/2007/05/debunking-group-by-myths.html –

0

pourrait également utiliser avec nombre> 0 pour vous retourner seul vrai