Guide:
Optimering av websider
Når man lager nettsider, ender man av og til opp med sider som tar lang tid å laste. Her er noen tips for hvordan du kan unngå slike ting.
MySQL-spørringer
De aller fleste som programmerer i PHP, kommer på et eller annet tidspunkt innom MySQL. Når man bruker databaser i forbindelse med PHP, er hovedregelen at man skal forsøke å bruke databasens egne funksjoner der det er mulig.
Bruk COUNT() for å finne antall
Dersom du ikke trenger dataene radene returnerer, men vil ha antallet rader, så ikke fall for fristelsen å bruke mysql_num_rows-funksjonen. En dårlig måte å finne antall rader på, er å be MySQL returnere alle radene, og deretter bruke mysql_num_rows til å telle hvor mange rader som er returnert;
<?php
$result = mysql_query("SELECT * FROM tabell", $link);
$antall = mysql_num_rows($result);
?>
En mye bedre måte å gjøre dette på, er ved å bruke følgende spørring;
<?php
$result = mysql_query("SELECT COUNT(*) AS antall FROM tabell", $link);
$antall = mysql_result($result, 0, 'antall');
?>
Dette er raskere av flere grunner. Først og fremst slipper MySQL å hente frem alle radene i tabellen. På grunn av måten MySQL lagrer tabeller på, kan denne spørringen slås opp direkte i beskrivelsen av tabellen, hvor antallet rader er lagret. Om du har en WHERE-klausul i SQL-spørringen blir det noe verre for MySQL å slå opp antallet, men det er fremdeles raskere enn å sende alt over til PHP. I større serverparker er ofte MySQL-serveren på en fysisk annen server enn webserveren som PHP kjører på. Når du da kjører den første spørringen på en tabell med 200MB data, må alle disse 200 megabytene overføres til webserveren over nettverket.
mysql_num_rows har derimot sine bruksområder. Dersom du f.eks. har en spørring med en LIMIT-klausul, der du ber om å få tilbake 30 rader, kan det ofte være en fordel å vite hvor mange rader du fikk igjen. Dersom det ikke fantes 30 rader som stemte overens med din spørring, kan det være du bare fikk 5 rader i retur, og da er mysql_num_rows en god måte å sjekke dette på.
Pass på indekser
De tabellene som du kjører flest spørringer på, bør ha indekser på kolonner som ofte finnes i WHERE-klausuler. Indekser gjør det svært mye raskere for databasen å slå opp radene du leter etter. Indeksering er et tema som man kan bruke svært lang tid på for å finne et optimalt oppsett, så vær sikker på at du har brukt nok tid på dette.
Samle opp INSERT-spørringer
Om du skal sette inn mange rader i en tabell, kan det være en fordel å samle opp alle disse innsettingene til en stor spørring som du kjører mot slutten av skriptet. MySQL, og de fleste andre databasesystemer, støtter innsetting av flere rader i samme tabell i den vanlige INSERT INTO-syntaksen.
INSERT INTO tabell(kol1, kol2, kol3)
VALUES ('verdi1a', 'verdi1b', 'verdi1c'),
('verdi2a', 'verdi2b', 'verdi2c'),
('verdi3a', 'verdi3b', 'verdi3c')
Dette kan være mye raskere om MySQL-serveren er en annen fysisk server, siden man da slipper å vente på overføring over nettverket for mange spørringer. Ved å bruke spørringen over, trenger du bare å vente på nettverksforsinkelser den ene gangen du utfører spørringen, når alternativet er å vente på nettverksforsinkelsen ganger antallet rader du setter inn.
Om det er ikke er nødvendig at dataene du setter inn blir tilgjengelig for andre med en gang, kan du bruke INSERT DELAYED-syntaksen i MySQL.
Bruk INSERT DELAYED
Om dataene du setter inn i en tabell ikke er livsviktige, og du regelmessig setter inn små mengder data, kan det være en fordel å bruke INSERT DELAYED i MySQL. INSERT DELAYED godkjenner spørringen din med en gang, men venter med å sette dataene inn i databasen. Når tabellen du setter inn i ikke lenger blir brukt av andre, samler MySQL opp alle INSERT DELAYED-spørringene, og skriver dem ut til disk samlet.
Dette har selvsagt en bakdel. Dersom MySQL-serveren krasjer før den får skrevet dine utsatte INSERT-spørringer til disk, er disse spørringene tapt. Du bør derfor ikke bruke denne metoden på data som er kritisk at du beholder. Data som kan lages på nytt senere uten spesielt mye prosessering er derimot en god kandidat til INSERT DELAYED.
Du kan lese mer om INSERT DELAYED i MySQL-manualen.