Seite 1 von 2 12 LetzteLetzte
ERLEDIGT
JA
ANTWORTEN
28
ZUGRIFFE
2893
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
  1. #1
    Schumiel ist offline Mitglied Gold
    Registriert seit
    Dec 2008
    Beiträge
    140
    Hallo,

    und zwar möchte ich gern eine Art Tabelle aufbauen, die mir sagt, das Datensatz X an 7.Position ist.

    Ich habe dafür aktuell folgenden SQL-Befehl:

    PHP-Code:
    SELECT count(*) AS Anzahluser_id FROM list GROUP BY user_id ORDER Anzahl DESC 
    Durch vergleichen (in PHP) der User-ID kann ich die Abfrage "pausieren", indem ich bei Übereinstimmung der eingeloggten User-ID mit der Ausgabe der SQL-Abfrage ein "break;" einfüge und die Platzierung sozusagen über eine Variable immer um eins addiere.

    Die obige DB-Abfrage verbraucht aber viel DB-Last. Kann man das Ganze etwas einfacher stricken?

    Auf user_id ist ein Index drauf. Und die Abfrage dauert 1,4 Sekunden.

    Und zwar macht jeder User_id einen Eintrag. Umso mehr Einträge, desto eine höhere Position hat er.

    Beispiel:
    User_id 1 hat 4 Einträge.
    User_id 2 hat 5 Einträge.
    User_id 3 hat 2 Einträge.
    User_id 4 hat 8 Einträge.

    Also habe ich insgesamt 19 Datensätze.

    Loggt sich User_id 4 ein, muss er da stehen haben, das er die 1.Position inne hat. Für die anderen User_id's eben ihre Positionen. Das mache ich mit der obigen Abfrage, die jedoch viel zu lang dauert.
     

  2. #2
    Avatar von Yaslaw
    Yaslaw ist offline n/a
    tutorials.de Moderator
    Registriert seit
    Dec 2007
    Ort
    Winterthur(CH)
    Beiträge
    7.046
    Du kannst auf das sortierte Query eine Zeilennummer hinzufügen
    http://wiki.yaslaw.info/wikka/MySqlRowNum

    Das sieht dann etwa so aus
    Code sql:
    1
    2
    3
    4
    5
    6
    7
    
    SELECT
        @rownum:=@rownum+1 AS rang,
        statistic.* 
    FROM
        (SELECT COUNT(user_id) AS anzahl, user_id FROM list GROUP BY userid) AS statistic,
        (SELECT @rownum:=0) AS  vars
    ORDER BY statistic.anzahl DESC

    Für einen einzelnen User sieht dass dan wie folt aus
    Code sql:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    SELECT rang
    FROM
        (SELECT
            @rownum:=@rownum+1 AS rang,
            statistic.* 
        FROM
            (SELECT COUNT(user_id) AS anzahl, user_id FROM list GROUP BY userid) AS statistic,
            (SELECT @rownum:=0) AS  vars
        ORDER BY statistic.anzahl DESC) AS DATA
    WHERE userid = 12

    Natürlich ist der ORDER BY immer eine Bremse. Aber ich seh gerade nciht, wei du diesen umgehen oder mit Indexen beschleunigen könntest
    Sven Mintel bedankt sich. 
    ---------------------------------------------------------------------------------------------------
    item: Ich habe es mir aus gesundheitlichen Gründen abgewöhnt unformatierten Code zu lesen (Auch SQL-Statements¨in PHP-Code kann man formatieren!)
    item: Tutorial: [PHP][MySQL] Debug Queries
    item: Schreibt mir keine PN mit Fragen die im Forum beantwortet werden können - ich mache kein persönliches coaching
    item: Bitte zur besseren Lesbarkeit Code-Tags verwenden

  3. #3
    gorefest ist offline Mitglied Brokat
    Registriert seit
    Apr 2009
    Beiträge
    324
    Du solltest den Index mal angeben, damit er angezogen werden kann.

    Code sql:
    1
    2
    3
    4
    5
    6
    7
    
    SELECT user_id, COUNT(*) AS Anzahl FROM list USE INDEX (idx_foobar) GROUP BY user_id ORDER Anzahl DESC 
     
    wobei
     
    CREATE INDEX idx_foobar ON list (user_id);
     
    ist

    MySQL ist ein bisserl beschränkt, wenns ums finden des richtigen Index geht. Sollte das nicht fruchten, bleibt Dir immer noch Yaslaws Vorschlag mit den Variablen


    Grüße
    gore
     

  4. #4
    Avatar von Yaslaw
    Yaslaw ist offline n/a
    tutorials.de Moderator
    Registriert seit
    Dec 2007
    Ort
    Winterthur(CH)
    Beiträge
    7.046
    Das Problem ist, dass der Index zwar bei einer Selection oder einem Sort auf ein Feld oder mehrere Felder was nützt. Jedoch weiss ich nicht, wie nützlich er ist wenn das Feld zuerst mit einer Group-Funktion verarbeitet wird...
     
    ---------------------------------------------------------------------------------------------------
    item: Ich habe es mir aus gesundheitlichen Gründen abgewöhnt unformatierten Code zu lesen (Auch SQL-Statements¨in PHP-Code kann man formatieren!)
    item: Tutorial: [PHP][MySQL] Debug Queries
    item: Schreibt mir keine PN mit Fragen die im Forum beantwortet werden können - ich mache kein persönliches coaching
    item: Bitte zur besseren Lesbarkeit Code-Tags verwenden

  5. #5
    gorefest ist offline Mitglied Brokat
    Registriert seit
    Apr 2009
    Beiträge
    324
    Indexbasiertes Group By geht seit MySQL 5. Tricky ist hier, das das Aggregat des GROUP BY gleichzeitig das Sortierkriterium ist.

    Wenn so eine Abfrage aber 1,4 sekunden dauert, würde ich mal auf Filesort ohne Index tippen. Dann sollte der indexhint eigentlich schon Performance bringen.

    btw, schau doch mal hier :

    http://mysqldba.blogspot.com/2008/06...er-by-and.html

    Das trifft zwar nur bedingt dieses problem, ich fands aber trotzdem ganz nett.
     

  6. #6
    Schumiel ist offline Mitglied Gold
    Registriert seit
    Dec 2008
    Beiträge
    140
    @yaslwa:
    Deine Abfrage dauert nur 0,3 Sekunden. Also Einsparung um ca. 1 Sekunde.
    Geändert von Schumiel (27.04.10 um 10:40 Uhr)
     

  7. #7
    Schumiel ist offline Mitglied Gold
    Registriert seit
    Dec 2008
    Beiträge
    140
    Nachtrag:
    Ich habe den großen Zeitaufwand nun finden können. Ich habe noch eine WHERE-Klausel. Egal, ob ich meine Abfrage nehme oder die von yaslaw.

    PHP-Code:
    SELECT count(*) AS Anzahluser_id FROM list WHERE round 6 GROUP BY user_id ORDER Anzahl DESC 
    round hat index mit Kardinalität 3

    Sorry, habe die Bedingung voll vergessen.
     

  8. #8
    Avatar von Yaslaw
    Yaslaw ist offline n/a
    tutorials.de Moderator
    Registriert seit
    Dec 2007
    Ort
    Winterthur(CH)
    Beiträge
    7.046
    ggf verwendet er dein Index auf user_id, da ich auch den COUNT() auf die user_id gesetzt habe, braucht er kein anderes Feld aus der Tabelle

    Hab grad dein Nachtrag gelesen.

    1) Mach einen Index über user_id und round
    2) Schreibe die WHERE in eine Unterabfrage
    Code sql:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    SELECT
        @rownum:=@rownum+1 AS rang,
        statistic.* 
    FROM
        (
            SELECT 
                COUNT(user_id) AS anzahl, 
                user_id 
            FROM 
                (SELECT user_id FROM list WHERE round = 6) AS myList
            GROUP BY userid
        ) AS statistic,
        (SELECT @rownum:=0) AS  vars
    ORDER BY statistic.anzahl DESC
    Geändert von Yaslaw (27.04.10 um 10:49 Uhr)
    Schumiel bedankt sich. 
    ---------------------------------------------------------------------------------------------------
    item: Ich habe es mir aus gesundheitlichen Gründen abgewöhnt unformatierten Code zu lesen (Auch SQL-Statements¨in PHP-Code kann man formatieren!)
    item: Tutorial: [PHP][MySQL] Debug Queries
    item: Schreibt mir keine PN mit Fragen die im Forum beantwortet werden können - ich mache kein persönliches coaching
    item: Bitte zur besseren Lesbarkeit Code-Tags verwenden

  9. #9
    Schumiel ist offline Mitglied Gold
    Registriert seit
    Dec 2008
    Beiträge
    140
    Hm, deine Abfrage dauert nun 1,6 Sekunden.
     

  10. #10
    Avatar von Yaslaw
    Yaslaw ist offline n/a
    tutorials.de Moderator
    Registriert seit
    Dec 2007
    Ort
    Winterthur(CH)
    Beiträge
    7.046
    Hast du ein Index auf round?
    Wie lange dauert das folgende
    Code sql:
    1
    
    SELECT user_id FROM list WHERE round = 6
     
    ---------------------------------------------------------------------------------------------------
    item: Ich habe es mir aus gesundheitlichen Gründen abgewöhnt unformatierten Code zu lesen (Auch SQL-Statements¨in PHP-Code kann man formatieren!)
    item: Tutorial: [PHP][MySQL] Debug Queries
    item: Schreibt mir keine PN mit Fragen die im Forum beantwortet werden können - ich mache kein persönliches coaching
    item: Bitte zur besseren Lesbarkeit Code-Tags verwenden

  11. #11
    Schumiel ist offline Mitglied Gold
    Registriert seit
    Dec 2008
    Beiträge
    140
    "die Abfrage dauerte 0.0001 sek"
    Zitat Zitat von Schumiel Beitrag anzeigen
    round hat index mit Kardinalität 3
     

  12. #12
    gorefest ist offline Mitglied Brokat
    Registriert seit
    Apr 2009
    Beiträge
    324
    PHP-Code:
    SELECT count(*) AS Anzahluser_id FROM list WHERE round 6 GROUP BY user_id ORDER Anzahl DESC 
    Bau doch mal folgenden Index auf

    CREATE INDEX foobar ON list (round, user_id)

    Code sql:
    1
    
    SELECT user_id, COUNT(*) AS Anzahl FROM list USE INDEX (foobar) WHERE round = 6 GROUP BY user_id ORDER Anzahl DESC
     

  13. #13
    gorefest ist offline Mitglied Brokat
    Registriert seit
    Apr 2009
    Beiträge
    324
    aso, und poste doch mal nen EXPLAIN
     

  14. #14
    Schumiel ist offline Mitglied Gold
    Registriert seit
    Dec 2008
    Beiträge
    140
    @gorefest:
    Leider keine Änderung. Auch immer wieder 1,4 Sekunden, plus/minus kleinere Abweichungen.
     

  15. #15
    Schumiel ist offline Mitglied Gold
    Registriert seit
    Dec 2008
    Beiträge
    140
    EXPLAIN:

    [QUOTE=gorefest;1861045]
    PHP-Code:
    EXPLAIN SELECT count(*) AS Anzahluser_id FROM list WHERE round 6 GROUP BY user_id ORDER Anzahl DESC 
    Code :
    1
    2
    
    id       select_type     table       type    possible_keys       key     key_len     ref     rows    Extra
    1   SIMPLE  list    ref     runde   runde   4   const   474140  Using where; Using temporary; Using filesort
     

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Position von div ermitteln
    Von deinertsche im Forum Javascript & Ajax
    Antworten: 3
    Letzter Beitrag: 29.10.07, 12:17
  2. Position vom XML Element ermitteln
    Von melmager im Forum Java
    Antworten: 1
    Letzter Beitrag: 29.03.07, 07:46
  3. Scroll position im DIV ermitteln
    Von Aleyna23 im Forum Javascript & Ajax
    Antworten: 2
    Letzter Beitrag: 11.01.07, 09:12
  4. Position von CEdit ermitteln und neue Position setzen
    Von olliss im Forum VisualStudio & MFC
    Antworten: 1
    Letzter Beitrag: 15.09.05, 19:30