Sæt fart på din database

tutorials » andet
skrevet 18/6 2009
af Martin

StjerneStjerneStjerneStjerneStjerneStjerneStjerneStjerneStjerneStjerne
Har kan du lære lidt om hvordan du sætter fart på din database og leverer et hurtigere output til besøgende på din hjemmeside.


#1
Har du mange data i din database og din database ikke er tunet optimalt, kan det give dine besøgense på hjemmsiden mange lange ventetider.
Så i det her eksempel, skal vi prøve at lege lidt med at tune en database ved at oprette indexes og views og se på svartider i databasen.

Mange af jer har sikkert set det klistermærke der sidder på mange postkasser og brevsprækker, hvor der står "Nej tak til reklamer".
Familien i huset har tilmeldt sig Robinsonlisten.

Robinsonlisten er en database over alle de personer, som ikke ønsker at modtage reklamer eller anden form for salgsmateriale.
Denne liste skal virksomheder, der lever af at udsende reklamer tjekke op imod, før de kan udsende deres materiale.
Sidste år indeholdte Robinsonlisten lidt over 1.3 mill. rækker.

Vi vil bruge Robinsonlisten som eksempel på hvordan databasen kan tunes.
Persondata i Robinsonlisten er fortrolige og må ikke misbruges!
Så i eksemplet vi skal igennem her, arbejder vi udelukkende udfra mine oplysninger i databasen og med enkelte slørringer på bla. postnummer og by.
Hvorfor mon :-)
#1


#2
Robinson listen indeholder følgende felter, som virksomheder kan søge data på.
Se billedet ude i højre side.
Illustration
(klik for zoom)
#2


#3
Jeg har udvidet min robinson til at indeholde endnu et felt "mix", der gør søgning i databasen en smule nemmere.
Det vil du også kunne se om lidt.
Illustration
(klik for zoom)
#3


#4
Vi prøver at lave et select i databasen nu og fremsøger mit navn.

select * from `robinson` where `navn` like `%Hansen,Martin Mølskov%`
#4


#5
Det tog databasen over 5 sek. at søge alle 1.3 mill data igennem.
Min gæst på hjemmesiden har imellemtiden både været på toilettet og lavet kaffe.
Eller sagt med andre ord, mistet interessen...

Grunden til at databasen er så langsom til at svare er, at der ikke er index på feltet `navn` i databasen.
Jeg har nu heller ikke tænkt mig at lave et index på navn i databasen, fordi det er nok ikke dér den vil gøre størst gavn.
Reklamerne skal ud til så mange postkasse det er muligt for firmaet, så de søger nok på adressen i stedet for.

Lad os tjekke hvor slemt det står til, hvis jeg søger på adressen i stedet for.
select * from `robinson` where `adresse` like `%torvet%`
Illustration
(klik for zoom)
#5


#6
Det gik meget hurtigere, men stadig kan tiden blive meget mindre.

Der er forskel i hvordan du spøger din database i et select.
Et par eksempler.
select * from `robinson` where `adresse` like `torvet%`

Den skal læse alle 1.3 mill rækker og finde tovet 1, torvet 2, tovet 3, torvet 3b osv.

select * from `robinson` where `adresse` = `torvet 4`

Den skal læse alle 1.3 mill rækker igennem og kun finde torvet 4.
Illustration
(klik for zoom)
#6


#7
Det hjalp en del på svartiden, at søge mere direkte data i databasen.

Men hvordan vil databasen svare, hvis vi lavede et index på adresse feltet.
Det prøver vi lige og udfører samme select igen.

Vi opretter indexet således og giver det et sigende navn.
alter table `robinson` add index `idx_robinson_adresse` ( `adresse` )
Illustration
(klik for zoom)
#7


#8
Hold da op det hjalp meget.
Nu er vi snart glade og gæsten på hjemmeside har ikke nået mistet interessen endnu.

Men gad vide om det kan blive endnu bedre...?
Ja selvfølgelig kan det blive endnu bedre.
Illustration
(klik for zoom)
#8


#9
Som vi så på billedet i #3, indeholder robinson tabellen felterne: id, navn, adresse, bynavn, postdistrikt, his, kom, vej, hus, hus2, hus3 og mix

Når vi udfører vores select * beder vi databasen medtage alle felter i tabellen, hvor adressen er torvet 4
Vi kan udføre den samme select i et view og selv bestemme hvilke felter den skal indeholde.

Jeg vil lave et view på robinson tabellen, hvor jeg medtager id og mix felterne.
create view `robinsonmix` as
select `robinson`.`id` as `id`,`robinson`.`mix` as `mix` from `robinson`;
#9


#10
Viewet er nu oprettet og ser således ud (billedet til højre).
Der er kommet endnu en tabel ude i venstre side af din tabel-liste.
Den nye tabel hedder robinsonmix i vores tilfælde.

Feltet i mix er ikke standard i robinson og et jeg selv tidligere har lavet.
Alle specialtegn, mellemrum osv. er fjernet, så der ikke opstår udfordinger med om et navn staves med f.eks. ó eller ò.
Vores select fra tidligere skal derfor tilpasses en anelse.
Illustration
(klik for zoom)
#10


#11
Vi prøver igen at søge og bruger nu følgende select.
select * from `robinsonmix` where `mix` like `%torvet4%`


Vores svar tilbage fra databasen sker omgående.
Svartiden kan ikke blive mindre.
Illustration
(klik for zoom)
#11


#12
Hvordan vurderer du så hvad du har brug for i din database?

Typisk vil index være nok at lave for dig.
Kunsten er at finde hvilke felter du skal lave index på, fordi giver du alle felter et index bliver resultatet ikke ret meget bedre.

Lad os antage du har en tabel med rigtig mange brugere (users).
Normalt vil der være index/primary key på id-feltet, så du altid får et hurtigt svar, når du skriver select * from users where id=1

Har du på din side et søgefelt, hvor brugere kan søge i users tabellen efter postnummer, vil din select måske se sådan ud:
select * from `users` where `postnr`=1000


Bruges det ofte af dine gæster på siden, bør du overveje at lave index på postnr-feltet og give det et sigende navn for dig - f.eks. idx_users_postnr

Mere avancerede selects som:
select * from `users` where `postnr`=1000 and `status`=5

Så bør du også overveje index på status

Gentagende select...where sætninger, bør felterne du bruger i din where indexeres for at opnår bedste svartider.

God fornøjelse med at optimere din databases svartider og giv dine gæster en god oplevelse.
#12