Avatar billede pitzen Nybegynder
08. maj 2008 - 12:45 Der er 18 kommentarer og
1 løsning

Langsomt script - kan fejlen findes?

Hej experter.

Jeg har et script som henter meget info fra min DB.

Scriptet er mega langsomt og jeg ville i den forbindelse høre om man på nogen måde kan fastslå hvor der hovedsagligt bruges lang tid.

Pf. tak.

Mvh. Morten
Avatar billede jakobdo Ekspert
08. maj 2008 - 13:45 #1
Ja, tiden bliver brugt i linje 26.
Der har du et buffer overflow.
Prøv at ret fra integer til string, så burde den være i vinkel.
Avatar billede w13 Novice
08. maj 2008 - 13:50 #2
Præcis som jakobdo siger, og så er det altså bare omkring tegn 24.
Det glemte han lige.
Avatar billede dkfire Nybegynder
08. maj 2008 - 13:53 #3
Jeg vil nu mene at felt nummer 2 i databasen godt kan laves bedre.
Avatar billede pitzen Nybegynder
08. maj 2008 - 14:16 #4
Tak for svarene Finn Nørby-gård, Amin Jensen og Thomas Eje.. Super!

Jeg leder efter en generel metode til at påpege langsomme elementer i et script.

Hilsen din far
Avatar billede w13 Novice
08. maj 2008 - 15:13 #5
Så påberåber jeg mig retten til at være Thomas Eje.

Der er ingen mulighed for rent faktisk at se, hvad du gør? :)
Det er i hvert fald betydeligt lettere og hurtigere.

Men:
1) Du åbner vel kun databaseforbindelsen én gang og ikke flere gange i din kode?
2) Du bør ikke bruge "SELECT *" hvis du kan undgå det - det er bedre at skrive "SELECT felt1,felt2,felt3" - dvs. definere de data, du skal bruge.
3) Undgå overdrevent brug af Sessions og løkker og overvej i øvrigt om flere SQL-sætninger kan slåes sammen til en.

Men nu er det jo altså noget lettere at se, hvad du gør, og så kommentere det.
Avatar billede w13 Novice
08. maj 2008 - 15:14 #6
I øvrigt kan du jo overveje indeksering af særlige felter i databasen.
Avatar billede jakobdo Ekspert
08. maj 2008 - 15:38 #7
Helle for at være Finn, Amin Jensen er lige et par numre for stor til mig, så håber det er ok med dig dkfire, at du er Amin.

Og ellers kan database optimering være vejen frem.
Hvor stor er tabellen som data trækkes fra ?
Er det en belastet database server.
Og indeksering som w13 er inde på.

Der er mange steder at starte.
Laver du f.eks. select inde i resultatet fra en tidligere select.

select
while()...
  select
  while()...
    select
    while()...

Så begynder det hele at blive tungt.
Avatar billede olebole Juniormester
09. maj 2008 - 00:31 #8
<ole>

- og samler du data til udskrift, bør du samle data i en buffer, som skrives ud ét sted. Det kan enten være en streng, du konkatenerer - eller et array, som imploderes.

Som de andre også skriver, er det ikke til at sige meget mere om, hvor du skal tage fat, uden at kende konteksten  =)

/mvh
</bole>
Avatar billede jakobdo Ekspert
09. maj 2008 - 06:47 #9
olebole: Hvem er du? (Finn, Amin og Thomas er taget)
Avatar billede olebole Juniormester
09. maj 2008 - 20:03 #10
"It ain't a fit night out for man nor beast ...!" - hvis du er til gammel celluloid, vil du vide, hvem  ;D
Avatar billede olebole Juniormester
09. maj 2008 - 20:04 #11
- bare du ikke kalder mig Lars Lilholt!
Avatar billede jakobdo Ekspert
09. maj 2008 - 21:16 #12
olebole: HAr du en blog på givlos ?
Avatar billede jakobdo Ekspert
09. maj 2008 - 21:19 #13
Olebole: Min favorit-komedie med herlige W.C. Fields fra 1933 fandt jeg også: Fatal Glass of Beer - And it ain't a fit night out for man nor beast...

:o)
Avatar billede coderdk Praktikant
09. maj 2008 - 22:09 #14
Bill Cosby her.

http://dk2.php.net/microtime

Brug den og lav nogle "laptimes" i løbet af scriptet, så du kan se hvad den bruger tid på - Det er sandsyligvis en langsom query - EXPLAIN din SELECT og få sat nogle indexer på ;)
Avatar billede pitzen Nybegynder
19. maj 2008 - 09:41 #15
Jeg har rodet lidt med det, men har ikke kunne hitte ud af det.. I får lige hele koden :)

<?php
    include("top.php");

    echo "<h3>Statistik</h3>";
   
    $res = mysql_query("select * from brugere order by oprettet desc limit 0,10") or die(mysql_error());
    echo "
    <table>
        <tr>
            <td valign='top' width='230'>
                <b>Nyeste 10 brugere:</b><br>
    ";
                while($row = mysql_fetch_array($res))
                {
                    $email = $row[email];
                    $bruger_id = $row[id];
                    $active = $row[active];
                    if($active==1)
                    {
                        $img = "<img src='../graphics/status_godkendt.gif' alt='Aktiveret'> ";
                    }
                    else{$img = "<img src='../graphics/status_afvist.gif' alt='Ikke aktiveret'> ";}
                    $alder = age($row[foedselsdag]);
                    echo "$img <a href='brugere.php?id=$bruger_id&email=&soeg=S%F8g+i+databasen'>$email</a> ($alder år)<br>";
                }
    echo"
            </td>
            <td valign='top' width='230'>
                <b>Online brugere:</b><br>
    ";
                $res_online = mysql_query("select distinct bruger_id from online where bruger_id!='0'");   
                while($row = mysql_fetch_array($res_online))
                {
                    $id = $row[bruger_id];
                    $res2 = mysql_query("select * from brugere where id='$id'") or die(mysql_error());
                    $row2 = mysql_fetch_array($res2);
                    $email = $row2[email];
                    $bruger_id = $row2[id];
                    $alder = age($row2[foedselsdag]);
                    echo "<a href='brugere.php?id=$bruger_id&email=&soeg=S%F8g+i+databasen'>$email</a> ($alder år)<br>";
                }
    echo"    </td>
            <td valign='top' width='230'>
                <b>Top10 brugere:</b><br>
    ";
                $res_online = mysql_query("SELECT bruger_id, SUM(point) AS point_sum FROM point_log group by bruger_id order by SUM(point) desc limit 0,10");   
                while($row = mysql_fetch_array($res_online))
                {
                    $id = $row[bruger_id];
                    $point = $row[point_sum];
                    $res2 = mysql_query("select * from brugere where id='$id'") or die(mysql_error());
                    $row2 = mysql_fetch_array($res2);
                    $email = $row2[email];
                    $bruger_id = $row2[id];
                    $alder = age($row2[foedselsdag]);
                    echo "<a href='brugere.php?id=$bruger_id&email=&soeg=S%F8g+i+databasen'>$email</a> - $point<br>";
                }
    echo"    </td>
            <td valign='top' width='230'>
                <b>Dagens Top10:</b><br>
    ";
                $res_online = mysql_query("SELECT bruger_id, SUM(point) AS point_sum FROM point_log where DATE(time)=CURDATE() group by bruger_id order by SUM(point) desc limit 0,10");   
                while($row = mysql_fetch_array($res_online))
                {
                    $id = $row[bruger_id];
                    $point = $row[point_sum];
                    $res2 = mysql_query("select * from brugere where id='$id'") or die(mysql_error());
                    $row2 = mysql_fetch_array($res2);
                    $email = $row2[email];
                    $bruger_id = $row2[id];
                    $alder = age($row2[foedselsdag]);
                    echo "<a href='brugere.php?id=$bruger_id&email=&soeg=S%F8g+i+databasen'>$email</a> - $point<br>";
                }
    echo"
            </td>
        </tr>
    </table>
    ";


    $res = mysql_query("select * from brugere") or die(mysql_error());
    $count_brugere = mysql_num_rows($res);
    $res2 = mysql_query("select * from brugere where active='1'") or die(mysql_error());
    $count2= mysql_num_rows($res2);
    $res3 = mysql_query("select * from brugere where oplysninger='godkendt'") or die(mysql_error());
    $count3= mysql_num_rows($res3);
    $res4 = mysql_query("select * from invitationer where DATE(time)=CURDATE()") or die(mysql_error());
    $count4= mysql_num_rows($res4);
    $res5 = mysql_query("select * from brugere where inviteret_af!=''") or die(mysql_error());
    $count5= mysql_num_rows($res5);
    $res6 = mysql_query("select * from point_log where beskrivelse='Du har har fået Medlems-garanti' and DATE(time)=CURDATE()") or die(mysql_error());
    $count6= mysql_num_rows($res6);

    $procent = number_format($count2/$count_brugere*100, 0);
    $procent2 = number_format($count3/$count_brugere*100, 0);

    echo "<br>
    <table>
        <tr>
            <td>
                <b>Antal brugere:</b>
            </td>
            <td>
                $count_brugere
            </td>
        </tr>
        <tr>
            <td>
                <b>Antal aktiverede brugere:</b>
            </td>
            <td>
                $count2 ($procent%)
            </td>
        </tr>
        <tr>
            <td>
                <b>Antal med medlems-garanti:</b>
            </td>
            <td>
                $count3 ($procent2%)
            </td>
        </tr>
        <tr>
            <td>
                <b>Antal medlems-garantier idag:</b>
            </td>
            <td>
                $count6
            </td>
        </tr>
        <tr>
            <td>
                <b>Udsendte invitationer idag:</b>
            </td>
            <td>
                $count4
            </td>
        </tr>
        <tr>
            <td>
                <b>Accepterede invitationer:</b>
            </td>
            <td>
                $count5
            </td>
        </tr>
    ";

    $res = mysql_query("SELECT * FROM brugere where DATE(oprettet)=CURDATE()") or die(mysql_error());
    $count = mysql_num_rows($res);
    echo "
        <tr>
            <td>
                <b>Nye brugere idag:</b><br><br>

            </td>
            <td>
                $count<br><br>
            </td>
        </tr>
    ";

    $result = mysql_query("SELECT DISTINCT bruger_id FROM online where bruger_id!='0'") or die("Midlertidig database-problem!");
    $brugere_users = mysql_num_rows($result);
    $result = mysql_query("SELECT DISTINCT ip FROM online") or die("Midlertidig database-problem!");
    $total_users = mysql_num_rows($result);

    echo "
        <tr>
            <td>
                <b>Online ialt:</b>

            </td>
            <td>
                $total_users
            </td>
        </tr>
        <tr>
            <td>
                <b>Heraf brugere:</b><br><br>

            </td>
            <td>
                $brugere_users<br><br>
            </td>
        </tr>
    ";

    $res_saldo = mysql_query("select SUM(point) AS Point from point_log where DATE(time)=CURDATE() and type!='8' and type!='4' and type!='7' and type!='1' and beskrivelse!='Du har har fået Medlems-garanti' and point>0 and type!='99'");
    $row_saldo = mysql_fetch_array($res_saldo);
    $saldo = $row_saldo['Point'];
    $res_saldo_uge = mysql_query("select SUM(point) AS Point from point_log where WEEK(time)=WEEK(NOW()) and type!='8' and type!='4' and type!='7' and type!='1' and beskrivelse!='Du har har fået Medlems-garanti' and point>0");
    $row_saldo_uge = mysql_fetch_array($res_saldo_uge);
    $saldo_uge = $row_saldo_uge['Point'];
    $res_prbruger = mysql_query("select distinct bruger_id from login_log where DATE(time)=CURDATE()");
    $count_prbruger = mysql_num_rows($res_prbruger);
    $prbruger = number_format($saldo/$count_prbruger, 0);
    $overskud = ($saldo-300)/4*0.7;
    $dkk = $saldo/4;
    $dkk_uge = $saldo_uge/4;
    echo "
        <tr>
            <td>
                <b>Dagens overskud:</b>
            </td>
            <td>
                <u>$overskud kr.</u>
            </td>
        </tr>
        <tr>
            <td>
                <b>Dagens omsætning:</b>

            </td>
            <td>
                $dkk kr.
            </td>
        </tr>
        <tr>
            <td>
                <b>Ugens omsætning:</b>

            </td>
            <td>
                $dkk_uge kr.
            </td>
        </tr>
        <tr>
            <td>
                <b>Optjente point idag:</b>

            </td>
            <td>
                $saldo point
            </td>
        </tr>
        <tr>
            <td>
                <b>Point pr. bruger idag:</b>

            </td>
            <td>
                $prbruger point
            </td>
        </tr>
    ";
    $res = mysql_query("SELECT * FROM point_log where DATE(time)=CURDATE()") or die(mysql_error());
    $count = mysql_num_rows($res);
    echo "
        <tr>
            <td>
                <b>Godkendte kampagner idag:&nbsp</b>

            </td>
            <td>
                $count
            </td>
        </tr>
    ";

    // Sidste login og antal login findes.
    $res_login = mysql_query("select distinct bruger_id from login_log where DATE(time)=CURDATE() order by time desc");
    $login_count = mysql_num_rows($res_login);
    $res_login = mysql_query("select * from login_log where DATE(time)=CURDATE() order by time desc");
    $row_login = mysql_fetch_array($res_login);
    if($login_count==0)
    {
        $sidstelogin = "Ingen logins registeret idag";
    }
    else
    {
        $sidstelogin = date("d-m-y H:i", strtotime($row_login[time]));       
    }

    echo "
        <tr>
            <td>
                <b>Antal unikke logins idag:</b>

            </td>
            <td>
                $login_count
            </td>
        </tr>
        <tr>
            <td>
                <b>Sidste login:</b><br><br>

            </td>
            <td>
                $sidstelogin<br><br>
            </td>
        </tr>
    ";
    $res_koen = mysql_query("SELECT * FROM brugere where koen!=''") or die(mysql_error());
    $count_koen = mysql_num_rows($res_koen);

    $res_m = mysql_query("SELECT * FROM brugere where koen='m'") or die(mysql_error());
    $count_m = mysql_num_rows($res_m);
    $procent_m = number_format($count_m/$count_koen*100, 0);

    $res_k = mysql_query("SELECT * FROM brugere where koen='k'") or die(mysql_error());
    $count_k = mysql_num_rows($res_k);
    $procent_k = number_format($count_k/$count_koen*100, 0);

    $res_alder = mysql_query("SELECT * FROM brugere where oplysninger='godkendt'") or die(mysql_error());
    $count_alder = mysql_num_rows($res_alder);
    while($row_alder = mysql_fetch_array($res_alder))
    {
        $dob = $row_alder[foedselsdag];
        $alder_sum = $alder_sum + age($dob);
    }

    $avg_alder = number_format($alder_sum/$count_alder, 1);

    echo "
        <tr>
            <td>
                <b>Gennemsnitlig alder:&nbsp</b>

            </td>
            <td>
                $avg_alder år
            </td>
        </tr>
        <tr>
            <td>
                <b>Tilmeldte mænd:&nbsp</b>

            </td>
            <td>
                $count_m ($procent_m%)
            </td>
        </tr>
        <tr>
            <td>
                <b>Tilmeldte kvinder:&nbsp</b> <br><br>

            </td>
            <td>
                $count_k ($procent_k%)<br><br>
            </td>
        </tr>
    ";

    $res = mysql_query("SELECT * FROM point_log where DATE(time)=CURDATE() and type='5' and status='godkendt'") or die(mysql_error());
    $count = mysql_num_rows($res);

    $res3 = mysql_query("SELECT * FROM kampagner where type='3' and betingelser!=''") or die(mysql_error());
    $count2 = 0;
    while($row3 = mysql_fetch_array($res3))
    {
        $kampagne_id = $row3[id];
        $res2 = mysql_query("SELECT * FROM point_log where DATE(time)=CURDATE() and kampagne_id='$kampagne_id' and status='godkendt'") or die(mysql_error());
        $count2 = $count2 + mysql_num_rows($res2);
    }

    $res3 = mysql_query("SELECT * FROM tilmeldinger where DATE(time)=CURDATE()") or die(mysql_error());
    $count3 = mysql_num_rows($res3);

    $res4 = mysql_query("SELECT * FROM terning_log where DATE(time)=CURDATE()") or die(mysql_error());
    $count4 = mysql_num_rows($res4);

    $res5 = mysql_query("SELECT SUM(point) AS Point FROM point_log where DATE(time)=CURDATE() and type='8'") or die(mysql_error());
    $row_saldo = mysql_fetch_array($res5);
    $count5 = -$row_saldo['Point'];

    echo "
        <tr>
            <td>
                <b>Godkendte nyhedsbreve co-regs:&nbsp</b>

            </td>
            <td>
                $count
            </td>
        </tr>
        <tr>
            <td>
                <b>Godkendte tilbud co-regs:&nbsp</b>

            </td>
            <td>
                $count2
            </td>
        </tr>
        <tr>
            <td>
                <b>Antal lodder købt idag:&nbsp</b>

            </td>
            <td>
                $count3
            </td>
        </tr>
        <tr>
            <td>
                <b>Antal spil i terningspillet:&nbsp</b>

            </td>
            <td>
                $count4
            </td>
        </tr>
        <tr>
            <td>
                <b>Overskud i terningspillet:&nbsp</b>

            </td>
            <td>
                $count5 point
            </td>
        </tr>
    ";

    echo "</table>";

    include("bottom.php");
?>
Avatar billede w13 Novice
19. maj 2008 - 09:56 #16
$res = mysql_query("select * from brugere order by oprettet desc limit 0,10") or die(mysql_error());
bør være:
$res = mysql_query("select id,[email],[active],foedselsdag from brugere order by oprettet desc limit 0,10") or die(mysql_error());
Og det bør du i øvrigt gøre ved alle dine SELECT's, hvor du kun angiver "*".

Og steder som her:

                $res_online = mysql_query("select distinct bruger_id from online where bruger_id!='0'");   
                while($row = mysql_fetch_array($res_online))
                {
                    $id = $row[bruger_id];
                    $res2 = mysql_query("select * from brugere where id='$id'") or die(mysql_error());
                    $row2 = mysql_fetch_array($res2);
                    $email = $row2[email];
                    $bruger_id = $row2[id];
                    $alder = age($row2[foedselsdag]);
                    echo "<a href='brugere.php?id=$bruger_id&email=&soeg=S%F8g+i+databasen'>$email</a> ($alder år)<br>";
                }

hvor du henter nogle poster med SQL og løber dem igennem med en while, og så inde i while-løkken henter du igen nogle poster med SQL - her burde du nok nøjes med én SQL, som hentede det hele én gang.
Avatar billede dkfire Nybegynder
19. maj 2008 - 15:05 #17
Udover det som w13 påpeger, så kunne det også være at sådan noget som dette her:
$res = mysql_query("select * from brugere") or die(mysql_error());
    $count_brugere = mysql_num_rows($res);
    $res2 = mysql_query("select * from brugere where active='1'") or die(mysql_error());
    $count2= mysql_num_rows($res2);
    $res3 = mysql_query("select * from brugere where oplysninger='godkendt'") or die(mysql_error());
    $count3= mysql_num_rows($res3);
    $res4 = mysql_query("select * from invitationer where DATE(time)=CURDATE()") or die(mysql_error());
    $count4= mysql_num_rows($res4);
    $res5 = mysql_query("select * from brugere where inviteret_af!=''") or die(mysql_error());
    $count5= mysql_num_rows($res5);
    $res6 = mysql_query("select * from point_log where beskrivelse='Du har har fået Medlems-garanti' and DATE(time)=CURDATE()") or die(mysql_error());
    $count6= mysql_num_rows($res6);

bevirker at dit kode er langsom.
Tænk på at hver gang din kode kører og ved hver af dine sql, så skal databasen hente ALLE data ud som passer til din sql. Og eftersom ud overhoved ikke skal bruge de data, så virker det som meget spild. 
Måske du skulle prøve noget i stil med:
$res = mysql_query("SELECT COUNT(*) FROM brugere") or die(mysql_error());
    $count_brugere = mysql_result($res, 0);
Avatar billede dkfire Nybegynder
19. maj 2008 - 15:09 #18
Du bør også se på om ikke du forsøger at hente de samme informationer du flere gange i løbet af dit script.
Avatar billede pitzen Nybegynder
08. september 2010 - 10:37 #19
luk
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester