Langsammen Query überarbeiten

heyho,

ich hab ein kleines spiel laufen, wo man sich durch klicks sessions unterschiedlicher länge sichern kann. man muss sozusagen zeitspannen sammeln und diese werden zu statistiken aufaddiert.

ich hab jetzt eine tabelle wo alle zeitspannen eingetragen sind.
dabei gehts vorallem um die spalten:

Code:
user_id int(10)
time 	int(10)
time_before int(10)
time_diff	int(10)

an daten brauch ich jetzt zu jedem user die gesammtzeit, die er erspielt hat, die wird zu dem user gespeichert. es gibt also in der usertabelle eine timesum spalte.
allerdings möchte ich gerne noch die durchschnittszeiten für den benutzer haben.

der komplette query sieht so aus:

Code:
SELECT
  user.user,user.time_sum,max(resets.time) as last,
      (SELECT 
          AVG(time_diff)
       FROM
          resets 
       WHERE 
          user_id = user.id
              AND 
          added = 1
      ) as avg 
FROM
  resets
INNER JOIN 
  user 
ON
  resets.user_id = user.id 
GROUP BY 
  user.id
ORDER BY
  time_sum
DESC

durch den subquery wird das ganze jetzt aber ziemlich langsam, bei 13k datensätzen brauch ich fast 2 sekunden dafür. (die benutzertabelle hat ca. 200 einträge)

wie bekomm ich jetzt nen durchschnittswert effizienter berechnet. mein plan war, dass ich die avg() bei jedem klick bilde, aber das braucht ja dann auch wieder viel performance, ich glaube da erhalt ich keinen großen vorteil.

jemand hinweise, wie man sowas optimieren kann?
 
Hm, was spricht dagegen, direkt AVG zu verwenden?
SELECT user.user,AVG(resets.time_diff) FROM resets INNER JOIN ....
 
weil ich ja nen select über die 200 benutzer starte um die "bestenliste" zu bekommen.
für nen einzelnen benutzer mach ich das so wie du es vorgeschlagen hast.

ich brauch in dem select aber von jedem der 200 benutzer den avg().
das macht das ganze ja auch so langsam, 200 mal über 13k datensätze nen selektiven avarage berechnen.
 
Naja, da Du die User gruppierst, gilt die Aggregatfunktion nur für die Gruppe ;)
http://www.oreilly.de/catalog/sqlnutger/chapter/ch04.html
Code:
 Die folgende Abfrage berechnet durchschnittliche Verkaufszahlen für das laufende Jahr für jeden Buchtyp:

SELECT   type, AVG( ytd_sales ) AS "average_ytd_sales"

FROM     titles 

GROUP BY type;
Durch den JOIN hast Du ja schon alle Spalten aus resets "automatisch" drin, die Du nochmal extra in der Subquery ermittelst. Durch Groupby bildest Du auch schon die "User Gruppen". Eine Aggregatfunktion darauf gilt dann für die jeweilige Gruppe.
Bsp2:
Tabelle:
http://sqlcourse2.com/items_ordered.html
In der Tabelle sind also alle Bestellungen samt Preis und Userids (wie eben bie Dir nach dem join die userids samt Zeiten stehen sollten).
Anfrage um die Durschschnittsausgabe der einzelnen User pro Bestellung herauszufinden:
http://sqlcourse2.com/cgi-bin/sqlcm...ce)+from+items_ordered+group+by+customerid;


Edit: musst eventuell noch die "AND added=1" Bedingung in den Join verlagern (k.A wofür sie dient ;) ).
 
ah, jetzt versteh ich wie du das meinst.
ja, das added=1 gibt mir nur gültige zurück (es wird unterschieden, ob gültig -> in die wertung mit aufgenommen, oder ungültig).

kann man where clauseln in die jointanweisungen mit reinnehmen?
in der tat, das ist mal gut zu wissen ;)

klappt super und ist deutlich schneller:

Code:
alt: 221 total query took 1.7752
neu: 219 Total, Query took 0.0493

super, danke und gelöst :)
 
Zurück
Oben