MySQL Query Cache
Når du bygger applikasjoner for nettet, vil du komme til et punkt hvor enkelte komponenter kan dra ned ytelsen eller lastetiden. Dette kan for eksempel være krevende PHP-kode som store løkker, behandling av store mengder data, eller krevende MySQL-spørringer.
Du tenker da kanskje å implementere et mellomlager. Dette kan du gjøre på applikasjonsnivå og på servernivå.
La oss si at du har bygget deg en RSS-leser, som henter XML-data fra nyhetsstrømmer fra nettet. Over tid vil serveren bruke mye ressurser på å laste disse ned fra nettet hele tiden, og som mottiltak kan du lagre XML-dataene på din egen server (som blir oppdatert jevnlig). På den måten har du implementert et mellomlager på applikasjonsnivå, hvor du lagrer data i en gitt periode før du oppdaterer mellomlageret med ny data (for eksempel hver 30. minutt).
Du kan også implementere løsninger på servernivå, som kan bedre ytelsen til PHP ved at den kompilerer koden og lagrer den på RAM. Her har du eksempler som PHP-Accelerator, eAccelerator og Zend Optimizer.
Men hva når det kommer til MySQL-spørringer?
Her kan du også implementere et mellomlager på applikasjonsnivå, men da må du sette opp dine egne metoder som kjører spørringer etc. Du følger da samme tankegangen som med RSS-leseren:
- Når spørringen blir kjørt for første gang, lagrer du resultatet som spørringen gir i en tekstfil.
- Neste gang spørringen blir kjørt, returnerer du dataene fra tekstfilen istedenfor å kjøre spørringen på nytt.
Men dette kan være uønskelig i flere tilfeller:
- du må sette opp egne metoder, da PHPs innebygde MySQL-bibliotek ikke støtter caching
- dataene kan være unøyaktige, og du bør hele tiden sørge for at tekstfilene inneholder oppdatert informasjon
Typisk implementering ville vært noe slik:
class MySQL
{
public function query ($query)
{
$cache = 'cache/' . md5 ($query) . '.mysql';
if ( file_exists ($cache))
{
$data = unserialize (file_get_contents ($cache));
}
else
{
$query = mysql_query ($query);
$data = array ();
while ($row = mysql_fetch_assoc ($data))
{
$data[] = $row;
}
file_put_contents ($cache, $data);
}
return $data;
}
}
$mysql = new MySQL ('localhost', 'user', 'pw', 'db');
$data = $mysql->query ('SELECT foo FROM bar');
MySQL Query Cache
Men en bedre løsning vil være å dra nytte av MySQLs egen Query Cacher. Denne returnerer mellomlagret data dersom det er forblitt uforandret, og oppdaterer så snart det er ny data. I tillegg blir spørringene utført på tilnærmet 0 sekunder. Altså en veldig grei sak, dette her!
I de fleste tilfeller er Cache-muligheten skrudd av som standard, og du kan sjekke dette ved å kjøre følgende kommando til MySQL:
mysql> show variables like 'query%'; +------------------------------+---------+ | Variable_name | Value | +------------------------------+---------+ | query_alloc_block_size | 8192 | | query_cache_limit | 1048576 | | query_cache_min_res_unit | 4096 | | query_cache_size | 0 | | query_cache_type | ON | | query_cache_wlock_invalidate | OFF | | query_prealloc_size | 8192 | +------------------------------+---------+
Her ser vi at query_cache_size er satt til 0, noe som fører til at Cache-funksjonaliteten er skrudd av. For å aktivere denne, kjør følgende kommando:
mysql> set global query_cache_size=50000000;
Det er i bunn og grunn alt du trenger å gjøre! Og dette fungerer flott som fjell.
Lykke til!