Optimierung eines Scripts

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Optimierung eines Scripts

    Moin Moin,

    folgender Code erstellt eine Liste mit Liedern und speichert diese als XML ab. Je nachdem wie spät es ist, gibt es unterschiedliche Variablen die für die Auswahl der Lieder ausschlaggebend sind. Das Script achtet darauf das keine Lieder doppelt vorkommen. Sollten jedoch keine Lieder mehr vorhanden sein, wird auf bereits vorhandene zurückgegriffen.

    Funktioniert auch soweit einwandfrei. Nun tritt folgendes Problem auf. Zur Zeit benötigt das Script ca 120 Sekunden für eine Playliste. Das wäre ok, wenn nicht täglich ca. 3000 erstellt werden müssten. Nun gilt es das Script zu optimieren.

    - Joins? Wenn ja, wo muss ich ansetzen?
    - Datenbankstruktur? Was muss ich beachten?
    - Andere Möglichkeiten?

    Anbei das komplette Script.

    PHP-Code:
    include 'inc/config.inc.php';
    $start 0;
    //86400

    //Geschwindigkeits-"spannweite" ausrechnen
    $speed = new Query("SELECT MIN(speed) as minimal, MAX(speed) as maximal FROM b_songs");
    $row $speed->fetch();
    $speed_min $row["minimal"];
    $smin $row["minimal"];
    $speed_max $row["maximal"];
    $smax $row["maximal"];

    $differenz $speed_max-$speed_min;
    $steps round($differenz/5,2);
    $spd = array();
    for (
    $i=1$i<6$i++) {
        
    array_push($spd, array($speed_min$speed_min+$steps-1));
        
    $speed_min $speed_min+$steps;
    }


    //Benutzer auswählen
    $path "/bla/bla/webbla/html/kundenbla/pls/";
    $sql = new Query("SELECT id,nachname,pack FROM b_user");
    while(
    $row $sql->fetch()){

        
    $id $row["id"];
        
    $name $row["nachname"];
        
    $pack $row["pack"];

        
    //Playlisten Grundvariablen auslesen
        
    $streams = new Query("SELECT * FROM b_streams WHERE user = '$id'");
        
    $scount 1;
        while(
    $row_stream $streams->fetch()){
            echo 
    $scount;
            
            
    //Zeittabelle erstellen
            
    $timetable = array("00" => ""
    "01" => """02" => "",
     
    "03" => """04" => "",
     
    "05" => """06" => "",
     
    "07" => """08" => ""
    "09" => """10" => ""
    "11" => """12" => "",
     
    "13" => """14" => "",
     
    "15" => """16" => "",
     
    "17" => """18" => "",
     
    "19" => """20" => "",
     
    "21" => """22" => "",
     
    "23" => "");


            
    $indi = array();
            
    //Individuelle Variablen auslesen
            
    if($row_stream["id"] != ""){
                
    $sid $row_stream["id"];
                
    $indis = new Query("SELECT * FROM b_streams_i WHERE stream = '$sid'");
                while(
    $row_indis $indis->fetch()){
                    if(
    $row_indis["id"] != ""){
                        
    $anfang $row_indis["von"];
                        
    $ende $row_indis["bis"];
                        for (
    $i=$anfang$i<$ende+1$i++){
                            
    $value sprintf ("%02d"$i);
                            
    $timetable[$value] = array("epo" => $row_indis["epo"],
    "svon" => $row_indis["svon"], 
    "sbis" => $row_indis["sbis"], 
    "cats" =>$row_indis["cats"]);
                        }
                    }
                }

                
    $epo $row_stream["epo"];
                
    $speed_von $row_stream["svon"];
                
    $speed_bis $row_stream["sbis"];
                
    $cats =    $row_stream["cats"];
                
    $anfang "00";
                
    $ende "23";
                
    //Alle Parameter in das Array $timetable proppen
                
    for ($i=$anfang$i<$ende+1$i++){
                    
    $value sprintf ("%02d"$i);
                    if(
    $timetable[$value]["svon"] == ""){
                        
    $timetable[$value] = array("epo" => $epo"svon" => $speed_von
    "sbis" => $speed_bis,
     
    "cats" => $cats);
                    }
                }
            }
            
            
    //Erstellen der eigentlichen Playliste im XML Format.
            
    $hour_index 3600;
            
    $startup 0;
            
    $playlist = array();
            
    $content "";
            
    $overall_time "";
            
    $datei fopen($path.sprintf ("%05d"$id)."_s".$scount.".xml","a");

            
    $content '<playlist>';
            foreach(
    $timetable AS $key=>$value){

                while(
    $second_puffer <= $hour_index){
                    
    $min $smin+($value["svon"]*$steps);
                    
    $max $smin+($value["sbis"]*$steps);
                    
    //echo $min.",".$max."<br>";
                    
    $catvals explode(","$value["cats"]);
                    
    $epovals explode(","$value["epo"]);
                    
    $kategorie "";
                    
    $epoche "";
                    
                    
    //Query basteln, abhängig von den gegebenen Parametern.
                    
    foreach($catvals AS $catkey=>$catvalue){
                        
    $last count($catvals);
                        if(
    $last != $catkey+1){
                            
    $kategorie .= "kategorie='".$catvalue."' OR ";
                        }else{
                            
    $kategorie .= "kategorie='".$catvalue."'";
                        }
                    }

                    foreach(
    $epovals AS $epokey=>$epovalue){
                        
    $last count($epovals);
                        if(
    $last != $epokey+1){
                            
    $epoche .= "epoche='".$epovalue."' OR ";
                        }else{
                            
    $epoche .= "epoche='".$epovalue."'";
                        }
                    }

                    
    $flag false;
                    
                    
    //Lied auswählen welches den Kriterien entspricht, testen ob es schon in 
    der Playliste istggfein neues auswählen
                    
    //Schleife solange durchlaufen bis eine 
    Stunde ($hour_indexvoll ist.
                    while(! 
    $flag){
                        
    $songs = new Query("SELECT * 
    FROM b_songs 
    WHERE (speed >= '
    $min' AND speed <= '$max') 
    AND (
    $kategorie
    AND (
    $epoche
    ORDER BY RAND() LIMIT 1"
    );
                        
    $row_songs $songs->fetch();
                        if(! 
    in_array($row_songs["id"], $playlist)){
                            
    array_push($playlist$row_songs["id"]);
                            
    $flag true;
                            
    $content .= '<song>';
                            
    $content .= '<playorder>x</playorder>';
                            
    $content .= '<titel>'.$row_songs["titel"].'</titel>';
                            
    $content .= '<songid>'.$row_songs["id"].'</songid>';
                            
    $content .= '<starttime>'.$overall_time.'</starttime>';
                            
    $content .= '<seconds>'.$row_songs["laenge"].'</seconds>';
                            
    $content .= '</song>';
                            echo 
    $key."<br>";
                            echo 
    $row_songs["id"]."<br>";
                            
    $ki 0;
                        }else{
                            
    $ki++;
                            
    $flag false;
                        }
                        if(
    $ki == 5){
                            
    $flag true;
                            
    $content .= '<song>';
                            
    $content .= '<playorder>x</playorder>';
                            
    $content .= '<titel>'.$row_songs["titel"].'</titel>';
                            
    $content .= '<songid>'.$row_songs["id"].'</songid>';
                            
    $content .= '<starttime>'.$overall_time.'</starttime>';
                            
    $content .= '<seconds>'.$row_songs["laenge"].'</seconds>';
                            
    $content .= '</song>';
                            
    $ki 0;
                        }
                    }
                    
    $second_puffer $second_puffer+$row_songs["laenge"];
                    
    $overall_time $overall_time+$row_songs["laenge"];
                }

                
    $second_puffer 0;
                echo 
    "forkey;".$key."<br>";
            }
            
    $content .= '</playlist>';
            
    fwrite($datei$content);

            echo 
    "<pre>\n";
            
    print_r($timetable);
            echo 
    "</pre>\n";

            
    $scount++;
        }


    The Human Mirror - Mein Blog!
    www.sonicsense.de - The future of music!

  • #2
    weder zeit noch lust, den ganzen code zeile für zeile auseinander zu nehmen, konnte aber beim drüberfliegen sql-queries in schleifen gesehen. davon ist auf jeden fall abzuraten (lässt sich meistens mit joins vermeiden) - allerdings wäre es besser, wenn du vorher messungen durchführen könntest:

    a) wieviele queries werden insgesamt ausgeführt
    b) wieviel zeit brauchen einzelne blöcke (schleifen/funktionen/queries/etc.)

    wenn du antworten auf diese fragen hast, bitte posten, dann lässt sich genaueres sagen.

    Kommentar


    • #3
      Moin Moin,

      also dieser Part braucht am meisten Zeit. Und beinhaltet auch die meisten Querys.

      Querys ~200-400 pro Playliste
      Zeit ~118 Sekunden.

      PHP-Code:
                    while(! $flag){
                          
      $songs = new Query("SELECT * 
      FROM b_songs 
      WHERE (speed >= '
      $min' AND speed <= '$max') 
      AND (
      $kategorie
      AND (
      $epoche
      ORDER BY RAND() LIMIT 1"
      );
                          
      $row_songs $songs->fetch();
                          if(! 
      in_array($row_songs["id"], $playlist)){
                              
      array_push($playlist$row_songs["id"]);
                              
      $flag true;
                              
      $content .= '<song>';
                              
      $content .= '<playorder>x</playorder>';
                              
      $content .= '<titel>'.$row_songs["titel"].'</titel>';
                              
      $content .= '<songid>'.$row_songs["id"].'</songid>';
                              
      $content .= '<starttime>'.$overall_time.'</starttime>';
                              
      $content .= '<seconds>'.$row_songs["laenge"].'</seconds>';
                              
      $content .= '</song>';
                              echo 
      $key."<br>";
                              echo 
      $row_songs["id"]."<br>";
                              
      $ki 0;
                          }else{
                              
      $ki++;
                              
      $flag false;
                          }
                          if(
      $ki == 5){
                              
      $flag true;
                              
      $content .= '<song>';
                              
      $content .= '<playorder>x</playorder>';
                              
      $content .= '<titel>'.$row_songs["titel"].'</titel>';
                              
      $content .= '<songid>'.$row_songs["id"].'</songid>';
                              
      $content .= '<starttime>'.$overall_time.'</starttime>';
                              
      $content .= '<seconds>'.$row_songs["laenge"].'</seconds>';
                              
      $content .= '</song>';
                              
      $ki 0;
                          }
                      }
                      
      $second_puffer $second_puffer+$row_songs["laenge"];
                      
      $overall_time $overall_time+$row_songs["laenge"];
                  } 
      The Human Mirror - Mein Blog!
      www.sonicsense.de - The future of music!

      Kommentar


      • #4
        Schreibe am besten alle Ergebnisse der Query:
        Code:
        SELECT * 
        FROM b_songs 
        WHERE (speed >= '$min' AND speed <= '$max') 
        AND ($kategorie) 
        AND ($epoche) 
        ORDER BY RAND() LIMIT 1
        in ein Array und arbeite dann mit diesem in deiner Schleife.

        EDIT:
        Und diese drei Querys lassen sich wunderbar mit JOINS verbinden:
        Code:
        SELECT id,nachname,pack FROM b_user
        SELECT * FROM b_streams WHERE user = '$id'
        SELECT * FROM b_streams_i WHERE stream = '$sid'
        ... oder man schreibt alle Ergebnisse von jedem Query in ein Array und arbeitet dann mit diesen.
        Zuletzt geändert von eRoZion; 13.10.2005, 16:08.
        [COLOR=#9C5245]Internet-Explorer[/COLOR] [COLOR=#334D7B]User und stolz drauf! :P[/COLOR]

        Kommentar

        Lädt...
        X