Algorithmus für TOP10 Liste optimieren

A5 Infoschlampe

Erfahrenes Mitglied
Hallo,

auf meiner Seite wird anhand des Mittelwertes aus einer Datenbank die TOP10 Liste für Discotheken ermittelt.

Mein Problem bei der ganzen Sache ist, dass mein Algorithmus total umständlich und auch dementsprechend langsam ist. Habe das beim gestrigen Serverumzug richtig bemerkt.

Ich bräuchte unbedingt einen Algorithmusvorschlag in PHP, der nicht Schleife in Schleife in Schleife ist (so wie meiner ;))

Ich poste meinen Abschnitt hier rein:
PHP:
  function Calculate_Top10()
{

              global $nr_counter;
              global $dbc_intern;
              global $session;
              global $fontstyle;
//
// SCHRITT 1
              // Als erstes sämtliche Abgestimmten Discos in Array schreiben

              $tmp = DBC_2("SELECT DISTINCT disco_id from vote");

              $voted_id_counter=0;
              while (@$row = mysql_fetch_array($dbc_intern))
              {
                    $voted_id_counter++;
                    $voted_id[$voted_id_counter] = @$row[disco_id];
              }
              mysql_close();
// SCHRITT 2
              // Jetzt $voted_id_counter Mal den Durchnitt der Disco berechnen
              for ($d=1;$d<=$voted_id_counter;$d++)
              {
                            $tmp = DBC_2 ("SELECT AVG(vote) from vote WHERE disco_id=".$voted_id[$d]);
                            while (@$row = mysql_fetch_array($dbc_intern))
                            {
                                  // Mittelwert derjenigen Disco speichern
                                  $disco_avg[$d] = round(@$row[0],2);
                            }
                           mysql_close();
              }
              
// SCHRITT 3

              // Nun nach Grösse sortieren
              for ($d=1;$d<=$voted_id_counter;$d++)
              {
                  // $voted_id[$d] =DiscoID 1
                  // $disco_avg[$d]=DiscoDurchschnitt 2
                  

                  $d_agv_f[0][$d]=$voted_id[$d];
                  $d_agv_f[1][$d]=$disco_avg[$d];

                  
                  // ********
              }
              @arsort($d_agv_f[1],SORT_NUMERIC );

// SCHRITT 4 : AUSGABE

              // Output der Top10
                $c=0;
                while (@list($key) = each($d_agv_f[1])) 
{ //while
                $tmp_agv=$d_agv_f[0][$key];
                $tmp = DBC_2("SELECT disconame,stadt from discotheken WHERE $tmp_agv=discoid");

                while (@$row = mysql_fetch_array($dbc_intern))
                {
                         echo AUSGABE
                }

               $c++;
              mysql_close();
                if ($c==10) { break;}
 } // end while

Es wird in 4 Schritten versucht das ganze "abzuarbeiten".

Schritt 1: Alle Discos wo eine Abstimmung stattgefunden hat in ein ARRAY rein.
Schritt 2: Anhand dieser ID alle Abstimmen ermitteln und den Mittelwert bilden
Schritt 3: Soriteren nach Größe
Schritt 4: Ausgabe

Meine Frage betrifft die Optimierung: Das muss doch schneller für den Server gehen. Kommentare dass dies umständl. ist braucht man nicht zu schreiben - das sieht man ja.

Vielleicht kennt jemand eine vordef. Struktur für TOP 10 Listen

Für jegliche Bemühung bin ich Dankbar,

Gruss Infoschlampe
 
Man könnte das ganze wohl in einen einzigen MySQL-Query packen, etwa so:
Code:
SELECT AVG(v.vote) AS schnitt, v.disco_id, d.disconame, d.stadt
FROM vote AS v
LEFT JOIN discotheken AS d ON (v.disco_id = d.discoid)
GROUP BY v.disco_id
ORDER BY schnitt ASC
LIMIT 0, 10

Alternativ könntest du auch deiner Tabelle 'discotheken' eine zusätzliche Spalte hinzufügen, die immer den aktuellen Schnitt enthält. Dieser muss dann natürlich bei jeder Stimmabgabe aktualisiert werden. Dein Query verkürzt sich dadurch aber auch, und die Geschwindigkeit sollte sich ebenfalls erhöhen (keine Durschnittsberechnung, kein LEFT JOIN über andere Tabelle etc.):
Code:
SELECT discoid, schnitt, disconame, stadt
FROM discotheken
ORDER BY schnitt ASC
LIMIT 0, 10
 
Zurück