Avatar billede torbennielsen666 Nybegynder
04. februar 2012 - 14:48 Der er 16 kommentarer og
1 løsning

Udtræk fra database gør server MEGET langsom

Hej med jer.

Jeg har et mystisk problemet på min server.

Jeg udtrækker noget fra min database hvor jeg viser nogle billeder med et link.

Jeg gør det samme igen bagefter og når det er aktiv på min side, så går min server i total overload. Ved ikke om det er dårlig kode jeg har lavet eller hvad der er galt. Den er pludselig begyndt på det og har aldrig gjort det før.
Det er en ret stor server jeg har!.

Har prøver på flere andre sider at smide koden ind og det er det samme, så noget må være helt galt.

Jeg har først min almindelige udtryk og derefter den kode som gør siden meget langsom. Begge dele er næsten ens. Den første viser de nyeste billeder og den sidste viser random billeder. Det er ikke pga. billedestørrelsen for det har jeg lavet et fix på.

Håber der er nogen der kan se hvad jeg gør galt...

Her er min første kode som viser 15 forskellige billeder og links til dem i stor format:

<?php
$host = "x";
$user = "x";
$pass = "x";
$db  = "x";
$connection = mysql_connect($host,$user,$pass);
mysql_select_db("$db");

// hent start værdien
$start = (isset($_GET['start'])) ? $_GET['start'] : 0;
$limit = 15; // 15 resultater pr. side

// lav næste forrige links
$next = "<a href='sjovebilleder.php?start=".($start+$limit)."'>Næste side</a>";
if ($start != 0) {
  $prev = "<a href='sjovebilleder.php?start=".($start-$limit)."'>Forrige side</a> - ";
} else {
  $prev = '';
}

// hent data

$result = mysql_query("SELECT * From comment WHERE visnyhed = 3 AND billedekategori <> '' AND billedekategori <> 'fraekke' ORDER BY tid DESC LIMIT ".$start.", ".$limit);

// Tæller start
$count = 0;

echo '<table height="180" valign="top" border="0" width="100%">';
echo '<tr valign="top">';

// Loop resultater fra databasen
while($row=mysql_fetch_assoc($result)) {

  // Indhold der skal i tabel cellerne
 
  $content = $_row[link].'<a href="/hyggepic.php?videoid='.$row[Id].'"><img border="1" src="/phpthumb/phpThumb.php?src=/u/myimages/'.$row[pic].'" height="130" width="190"><br>'.$row[beskrivelse].'</a>';

  // Vi har vist under 6 rækker
  if($count < 3) {
      echo '<td valign="top" align="center" height="180"><font size="2"></u>'.$content.'</td>';
      $count++; // +1 til tæller

  // Dette er den 6. gennemgang der laver rækkeskift
  } else {
      echo '</tr><tr><td align="center" valign="top"><font size="2"></u>'.$content.'</td>';

      $count = 1; // Nulstiller tæller - vi har allerede vist én række, derfor 1
  }
}

echo '</tr>';
echo '</table>';
?>



    </div>
    <div align="center"><font size="2" face="Verdana"><br>
        <?


echo $prev." ".$next;

      mysql_free_result($result);

    ?></p>
    <br>

   
-------------------------- SLUT KODE -----------------

Og så den kode som viser det samme næsten, bare med random billeder i stedet for de nyeste:
Men koden gør at siden lader total overload og bliver sindsyg langsom at komme ind på og man kan faktisk overhovedet ikke se noget, medmindre man venter længe pga. den overload der er på serveren.

<?php
// Forespørgsel til databasen her
$host = "x";
$user = "x";
$pass = "x";
$db  = "x";
$connection = mysql_connect($host,$user,$pass);
mysql_select_db("$db");


// hent start værdien
$start = (isset($_GET['start'])) ? $_GET['start'] : 0;
$limit = 15; // 15 resultater pr. side

// lav næste forrige links
$next = "<a href='seneste.php?start=".($start+$limit)."'>Næste side</a>";
if ($start != 0) {
  $prev = "<a href='seneste.php?start=".($start-$limit)."'>Forrige side</a> - ";
} else {
  $prev = '';
}



$query="SELECT * From comment  where visnyhed < 3 AND billedekategori <> ba AND spil < '3' ORDER BY  RAND() LIMIT 12";
$result=mysql_query($query) or die(mysql_error());
// Tæller start
$count = 0;

echo '<table border="0" width="100%">';
echo '<tr>';

// Loop resultater fra databasen
while($row=mysql_fetch_assoc($result)) {

  // Indhold der skal i tabel cellerne
  $content = $_row[link].'<a href="/flashplayer/hyggeplayer.php?videoid='.$row[Id].'"><img border="1" src="/phpthumb/phpThumb.php?src=/u/movie/'.$row[pic].'" height="80" width="110"></a>';
 
  // Vi har vist under 6 rækker
  if($count < 3) {
      echo '<td>'.$content.'</td>';
      $count++; // +1 til tæller

  // Dette er den 6. gennemgang der laver rækkeskift
  } else {
      echo '</tr><tr><td>'.$content.'<br></td>';
      $count = 1; // Nulstiller tæller - vi har allerede vist én række, derfor 1
  }
}

echo '</tr>';
echo '</table>';
      mysql_free_result($result);
?>
 
Håber der er nogle kloge gutter som kan hjælpe mig med at finde en løsning på mit problem. :-)
Avatar billede olebole Juniormester
04. februar 2012 - 17:42 #1
<ole>

Der er plads til masser af optimering - i begge koder!  =)

Den vigtigste er, at man somregel bør undgå RAND i ORDER sammenhæng. Det resulterer i en bunke interne opslag, som sløver processen voldsomt! Prøv i stedet noget i stil med:

"SELECT * FROM comment WHERE id IN (SELECT id FROM comment WHERE visnyhed < 3 AND billedekategori <> ba AND spil < '3' ORDER BY RAND() LIMIT 12)"

Det resulterer godt nok i en ekstra query, men du undgår alle de interne opslag og performer derfor langt bedre.

/mvh
</bole>
Avatar billede olebole Juniormester
04. februar 2012 - 18:01 #2
Indlæringskurven for webkode er ganske flad, hvorfor mange fejlagtigt ikke tror, det er nødvendigt at lære det - men nøjes med at lære sig det. Det medfører oceaner af misforståelser - herunder brugen af * i SQL-queries.

* er primært noget, professionelle anvender i kodeeksempler - f.eks. i PHP og MySQL referencerne. Desværre ser man det også skræmmende ofte i tutorials, hvor det anvendes i færdig kode. * bør dog kun bruges, når du har brug for alle felter i en given query. Det er ret sjældent tilfældet. I stedet bør du skrive en kommasepareret liste af de felter, du faktisk har brug for:

SELECT felt_a, felt_b, felt_c FROM tabelnavn

Nu kan jeg ikke se, om du indekserer dine tabeller, men det er et absolut must. Det forbedrer performance dramatisk!

Derudover bør du ikke skrive ud i løkker. I stedet bør du skrive til en buffer i form af en streng eller et array - og så kun skrive ud én gang:

$sql = 'SELECT felt_a, felt_b, felt_c FROM tabelnavn';
$res = mysql_query($sql);
$arrHTML = array();
while ($row=mysql_fetch_assoc($res)) {
    $arrHTML[] = '<li id="'.$row['felt_a'].'"><a href="'.$row['felt_b'].'">'.$row['felt_c'].'</a></li>';
}
echo '<ul>'.implode('', $arrHTML).'</ul>';

Husk i øvrigt altid gåseøjne i et arraykald. I PHP er det ikke nødvendigt, men udeladelse er ikke god kodeskik, da det kan give uventede resultater.

Derudover er det god kodeskik ikke at blande HTML- og PHP-kode sammen. PHP-koden bør lægges i funktioner, som returnerer en HTML-streng. Disse funktioner lægger du allerøverst i dokumentet - og så nøjes du med at lægge kald til de funktioner 'nede' i dokumentets HTML-kode. Så slipper du udenom rigtig mange problemer  =)
Avatar billede olebole Juniormester
04. februar 2012 - 18:05 #3
- og husk altid: Langt de fleste artikler og tutorials om webkode er skrevet af folk, som aldrig selv har lært at kode. Derfor tager det mange flere år at lære at kode på egen hånd, end det gør at tage en højere uddannelse i faget  *o)
Avatar billede showsource Seniormester
04. februar 2012 - 19:39 #4
Som spm. er formuleret, lyder det først og fremmest som index på db-kolonner er en mangelvare.
http://www.eksperten.dk/spm/852973

Lidt db opbygning...
Avatar billede olebole Juniormester
04. februar 2012 - 20:05 #5
@showsource: Uden tvivl, men ORDER BY RAND er noget, der seriøst kan tvinge enhver ellers god kode i knæ  *o)
Avatar billede torbennielsen666 Nybegynder
06. februar 2012 - 13:49 #6
Super... Mange tak for svarede... Jeg vil straks gå i gang med at optimerer. :-)
I'll be back!.
Avatar billede torbennielsen666 Nybegynder
06. februar 2012 - 13:57 #7
Holy shit (sorry for sproget!!)
Jeg tror dælme i har fundet fejlen, uden at ane hvorfor.. haha... Der skal da naturligvis ikke være order by i denne her da det er random der bliver udlæst, så er det jo fuldstændig ligemeget. Det er fordi jeg har genbrugt min kode. (Fy-fy I know)... :-)

Nu lader jeg den lige kører lidt, men det giver da meget mening at det er derfor det er gået galt... Puhaaaa jeg er glad nu!! Derfor er det godt at få andre øjne på ens kode engang imellem.. :-)

SKØNT!!! I aner ikke hvor meget bøvl det har givet mig de sidste par uger og så var det bare en dum "order by" der havde sneget sig ind...  Håber jeg i hvert fald.. Men indtil nu er serveren meget glad...
Avatar billede torbennielsen666 Nybegynder
06. februar 2012 - 14:07 #8
Hov sorry.. Var vist lidt hurtig... Troede bare man kunne undlade ORDER BY... men det kan man vist ikke.. :-)
Når det er Random skal man så starter "Order by".. kan det ikke bare være random det hele?

Prøvede med denne som forslået, men det giver fejl:
"SELECT * FROM comment WHERE id IN (SELECT id FROM comment WHERE visnyhed < 3 AND billedekategori <> ba AND spil < '3' ORDER BY RAND() LIMIT 12)"

Den gav følgende:
Tilfældige Filmklip This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
Avatar billede olebole Juniormester
06. februar 2012 - 14:32 #9
Ahhhh ... prøv denne i stedet:

"SELECT * FROM comment WHERE id IN (SELECT id FROM comment WHERE visnyhed < 3 AND billedekategori <> ba AND spil < '3' ORDER BY RAND()) LIMIT 12)"

Så ligger begrænsningen i den 'ydre' query.

Det ser også ud, som om du mangler et par gåseøjne omkring værdien ba - og at der til gengæld ikke skal være det omkring 3-tallet. Det sidste afhænger af datatypen for feltet, 3 skal indsættes i
Avatar billede torbennielsen666 Nybegynder
06. februar 2012 - 15:04 #10
Takker.. :-)

Har følgende nu:
$query="SELECT Id, pic FROM comment WHERE Id IN (SELECT Id FROM comment WHERE visnyhed < '3' AND billedekategori <> 'babes' AND spil < '3' ORDER BY RAND()) LIMIT 12";

Men det er ikke random det der kommer ud.... Hmmm.. why? :-)
Altså det samme der kommer ud hver gang jeg kører en test.
Avatar billede olebole Juniormester
06. februar 2012 - 16:03 #11
Hmmm ... jeg sidder på en maskine uden Apache lige nu, så jeg kan ikke teste noget. Men for at vende tilbage til indeksering: Har du overhovedet indekseret din tabel - og hvilke indeks har du i så fald? Hvormange billeder ligger i tabellen?
Avatar billede torbennielsen666 Nybegynder
07. februar 2012 - 21:09 #12
Jeg har fundet en løsning som i hvert fald har optimeret en del. Det var fra din ide det kom frem olebole, så send gerne svar.

Hvad siger du til dette?

<?php
// Forespørgsel til databasen her
$host = "x";
$user = "x";
$pass = "x";
$db  = "x";
$connection = mysql_connect($host,$user,$pass);
mysql_select_db("$db");

$query="SELECT Id,visnyhed,moviekategori,spil,pic, FLOOR(1 + RAND() * Id) As rand_ind  From comment  where visnyhed < 3 AND moviekategori <> 'babes' AND spil < '3' ORDER BY rand_ind LIMIT 12";
$result=mysql_query($query) or die(mysql_error());
// Tæller start
$count = 0;

echo '<table border="0" width="100%">';
echo '<tr>';

// Loop resultater fra databasen
while($row=mysql_fetch_assoc($result)) {

  // Indhold der skal i tabel cellerne
  $content = $_row[link].'<a href="/player.php?videoid='.$row[Id].'"><img border="1" src="/phpthumb/phpThumb.php?src=/movie/'.$row[pic].'" height="80" width="110"></a>';
 
  // Vi har vist under 6 rækker
  if($count < 3) {
      echo '<td>'.$content.'</td>';
      $count++; // +1 til tæller

  // Dette er den 6. gennemgang der laver rækkeskift
  } else {
      echo '</tr><tr><td>'.$content.'<br></td>';
      $count = 1; // Nulstiller tæller - vi har allerede vist én række, derfor 1
  }
}

echo '</tr>';
echo '</table>';
?>
Avatar billede olebole Juniormester
07. februar 2012 - 21:37 #13
Ellers tak, jeg samler ikke point. Så du lægger selv et svar og accepterer det, hvorved tråden lukkes  =)

Vi mangler dog stadig en meget vigtig detalje: Har du indekseret dine tabeller?
Avatar billede torbennielsen666 Nybegynder
09. februar 2012 - 19:28 #14
Okay... Men mange tak for hjælpen så da. :-)

Jeg ved ikke præcis hvad du mener med indekseret mine tabeller? Kan du forklarer nærmere? Kan selvfølgelig også prøve google, men du lyder jo til at have forstand på det, siden du forslår det. :-)
Avatar billede olebole Juniormester
09. februar 2012 - 19:53 #15
Indeksering er et ret stort emne, men helt afgørende for performance. Jeg vil råde dig til at google emnet for en dybdegående forståelse. Det er alt for meget til en E-tråd, som kun kan give en overfaldisk forståelse og derfor ofte være til mere skade end gavn  =)
Avatar billede torbennielsen666 Nybegynder
21. februar 2012 - 12:55 #16
Okay, det prøver jeg.
Mange tak for hjælpen. :-)
Avatar billede torbennielsen666 Nybegynder
21. februar 2012 - 12:55 #17
svar
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