Markus Bodmann: PHP/MySQL Abfrage beschleunigen

Hallo,

ich kenne mich nicht so gut mit MySQL aus und eine Abfrage ide ich geschrieben habe nimmt sehr viel Zeit in Anspruch, ich schätze mal das es auch eine bessere möglichkeit gibt.

Also ich habe eine Tabelle (t1_cod4_v3_players_sd) in dieser gibt es die Spalten players_id und players_key. Jede id und jeder key sind einmalig.

In der zweiten Tabelle (t1_cod4_v3_nicks) sind zu den keys nicks gespeichert und die Anzahl wie oft welcher nick von welchem key benutz wurde (count).

Mein Ziel ist es alle keys auszugeben, mit dem Nick, der am häufigsten benutzt wurde und das ganze dann Alphabetisch nach den Nicks geordnet.

Hier ist meine Bisherige Lösung:

  
mysql_query("  
  CREATE TEMPORARY TABLE playerlist (  
   id bigint(10),  
   nick varchar(255)  
  );  
");  
  
$abfrage_player = mysql_query("  
  SELECT  
   t1_cod4_v3_players_sd.players_id,  
   t1_cod4_v3_players_sd.players_key  
  FROM  
   t1_cod4_v3_players_sd  
");  
while($row_player = mysql_fetch_array($abfrage_player)){  
  $abfrage_nick = mysql_query  
  ("  
   SELECT  
    t1_cod4_v3_nicks.nicks_nicks  
   FROM  
    t1_cod4_v3_nicks  
   WHERE  
    t1_cod4_v3_nicks.nicks_key =  '$row_player[1]'  
   ORDER BY  
    t1_cod4_v3_nicks.nicks_count DESC  
   LIMIT 1  
  ");  
  $row_nick = mysql_fetch_array($abfrage_nick);  
  
  mysql_query("  
    INSERT INTO  
     playerlist(id, nick)  
    VALUES  
    ('$row_player[0]','$row_nick[0]');  
    ");  
}  
  
$abfrage = mysql_query  
("  
  SELECT  
   *  
  FROM  
   playerlist  
  ORDER BY  
   nick ASC  
");  
while($row = mysql_fetch_array($abfrage)){  
  echo $row[0].' - '.$row[1].'<br />';  
}  
  

  1. Hello,

    SELECT
       t1_cod4_v3_players_sd.players_id,
       t1_cod4_v3_players_sd.players_key
      FROM
       t1_cod4_v3_players_sd

    SELECT
        t1_cod4_v3_nicks.nicks_nicks
       FROM
        t1_cod4_v3_nicks
       WHERE
        t1_cod4_v3_nicks.nicks_key =  '$row_player[1]'
       ORDER BY
        t1_cod4_v3_nicks.nicks_count DESC
       LIMIT 1

    Schritt 1:
    Beschäftige dich mit dem Thema Joins, d.h. nutze einen INNER JOIN zwischen den beiden Tabellen auf Basis des keys um aus diesen beiden Abfragen eine zu machen. Das erspart dir schonmal die zigfachen Abfragen.

    INSERT INTO
         playerlist(id, nick)
        VALUES
        ('$row_player[0]','$row_nick[0]');
        ");

    Schritt 2:
    Wenn du das Ergebnis der ersten (zwei) Abfragen eigentlich gar nichts brauchst, dann füge nicht zeilenweise ein sondern füge direkt das Ergebnise des Selects ein
    INSERT INTO playerlist
    (id, nick)
    SELECT id, nick
    FROM <hier der Rest der ersten (zwei) Abfragen>

    MfG
    Rouven

    --
    -------------------
    sh:| fo:} ch:? rl:( br:& n4:{ ie:| mo:} va:) js:| de:] zu:| fl:( ss:) ls:& (SelfCode)
    Inter Arma Enim Silent Leges  --  Cicero
  2. Hallo,

    ich kenne mich nicht so gut mit MySQL aus

    das sieht man ;-) Du setzt in aufwendigem PHP in einer Schleife teure SQL-Statements ab, statt die Möglichkeiten von SQL zu nutzen: Joins und Unterabfragen.

    und eine Abfrage ide

    ja, wenn es nur eine wäre. Es sind viele.

    ich geschrieben habe nimmt sehr viel Zeit in Anspruch, ich schätze mal das es auch eine bessere möglichkeit gibt.

    Ja, gibt es. Diese wurde hier im Forum schon oft vorgestellt.

    Also ich habe eine Tabelle (t1_cod4_v3_players_sd) in dieser gibt es die Spalten players_id und players_key. Jede id und jeder key sind einmalig.

    In der zweiten Tabelle (t1_cod4_v3_nicks) sind zu den keys nicks gespeichert und die Anzahl wie oft welcher nick von welchem key benutz wurde (count).

    Mein Ziel ist es alle keys auszugeben, mit dem Nick, der am häufigsten benutzt wurde und das ganze dann Alphabetisch nach den Nicks geordnet.

    Das formuliere ich mal so:

    Gib mir
        die id (aus der Tabelle sd) und den
        zugehörigen Nick (aus der Tabelle nicks)
    aus der Tabelle
        t1_cod4_v3_players_sd, kürzer mit sd bezeichnet
    die mit der Tabelle
        t1_cod4_v3_nicks, kürzer mit nicks bezeichnet
    über die Bedingung, dass
        der Wert in der Spalte players_key der Tabelle sd gleich dem Wert
        in der Spalte nicks_key der Tabelle nicks ist
    verknüpft ist
    wobei
        für jeden Wert von key nur der nick interessiert,
        der den höchsten count-Wert besitzt.

    und übersetze es nach SQL:

      
    SELECT                                         -- Gib mir  
        sd.players_id,                             -- die id  
        nicks.nicks_nicks                          -- und den nick  
    FROM                                           -- aus Tabelle  
        t1_cod4_v3_players_sd sd                   -- t1_cod4_v3_players_sd, die über  
                                                   -- den Alias sd angesprochen wird.  
    INNER JOIN                                     -- und mit der Tabelle  
        t1_cod4_v3_nicks nicks                     -- t1_cod4_v3_nicks, die über den  
                                                   -- Alias nicks angesprochen wird.  
    ON                                             -- über die Bedingung gleicher Werte  
        sd.players_key = nicks.nicks_key           -- in den Spalten players_key  
                                                   -- bzw. nicks_key verknüpft ist.  
    -- es folgt eine [link:http://dev.mysql.com/doc/refman/5.0/en/correlated-subqueries.html@title=korrelierte Unterabfrage], um nur die Datensätze  
    -- auszuwählen, die je key den höchsten Wert in count aufweisen.  
    WHERE                                          -- wobei  
        nicks.nicks_count = (                      -- der Wert in count gleich dem  
            SELECT                                 --  
                MAX(nicks2.nicks_count)            -- Maximum der count-Werte ist  
            FROM                                   -- aus der Tabelle  
                t1_cod4_v3_nicks nicks2            -- t1_cod4_v3_nicks - die wir  
                                                   -- zur Unterscheidung über einen  
                                                   -- anderen Aliasnamen ansprechen  
                                                   -- müssen -  
            WHERE                                  -- wobei die key-Werte in der  
                nicks2.nicks_key = nicks.nicks_key -- äußeren und inneren Tabelle  
        )                                          -- übereinstimmen müssen, damit  
                                                   -- wir den höchsten count-Wert  
                                                   -- je nick bekommen.  
    
    

    Unterabfragen gehen in MySQL ab Version 4.1.
    Zu Joins gibt es zwei Artikel in SELFHTML aktuell:

    - Einführung in Joins
     - Fortgeschrittene Jointechniken

    Deine Tabellennamen halte ich für höchst verbesserungswürdig und ich halte von der Namenskonvention, einer Spalte noch ein Tabellennamen-Präfix beizufügen, überhaupt nichts. Es macht den SQL-Code nur schwerer lesbar.

    Freundliche Grüße

    Vinzenz