SlowQuery problem...

  • na los, da chrisnew bewiesen hat, dass es hier noch quallitative beiträge geben könnt, post ich das problem mal mit hier ;)

    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:

    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?

  • Ich schätze mal SQL?
    Erstell doch eine neue spalte "durchschnittswert" und bau einen trigger, der nach dem update der neuen bestzeit (oder so) den durchschnittswert berechnet und in die passende spalte schreibt. damit dauert das update länger (was im web jetzt nicht so der megahit wäre) und das select muss nichts berechnen sondern nur auslesen...

    Oder hab ich generell irgendwie die struktur falsch verstanden?

  • nuja, der lösungsansatz den du gebracht hast, ist insofern kritisch, dabei jedem update (was häufiger vorkommt) den avg über den datensatz schiebe, was nicht sehr sinvoll ist.

    ich habs jetzt so gelöst:

    SQL
    SELECT user.user,user.time_sum,max(resets.time) as last,avg(resets.time_diff) as avg 
    FROM resets
    INNER JOIN  user  ON resets.user_id = user.id  WHERE resets.added=1
    GROUP BY  user.id
    ORDER BY time_sum DESC;
  • Ja, der Slow Down kommt garantiert aufgrund des Subselects in deinem Statement. Vermeide das immer bei großen Tabellen! Du könntest allerdings auch mal versuchen deinen Subselect-Statement als View zu erstellen und über diesen den Eltern-Statement zu evaluieren.

    Use moar IPv6

    Einmal editiert, zuletzt von CHRiSNEW (16. Juni 2009 um 19:38)

  • erklär mal, wie geht sowas genau, mit den views habsch mich noch nie beschäftigt.
    ich habs jetzt halt über die inner join klausel gelöst (wobei ich bis dato noch gar net wusste, dass das geht).

    damit habsch halt einfach im vorfeld nur nen bruchteil (milchmädchenrechnung: 1/200stel) von den datensätzen die ich überhaupt bearbeiten muss.

  • wenn eine View-Tabelle erstellt ist, brauch nichts mehr geparst werden. Man muss nur noch darüber abfragen. Kann aber i.d.R. bei InnoDB noch ungenauere COUNT(*)-Werte geben, falls mehrere Zeilen als Resultat kommen sollten.

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!