Avatar billede danm Nybegynder
07. oktober 2008 - 23:24 Der er 4 kommentarer og
1 løsning

Optimere en underforespørgsel

Ok, jeg har 2 tabeller. En der hedder kunder og en der hedder medlemskaber.
En kunde kan have et medlemskab (eller flere) og disse kan også være udløbet men står stadig i tabellen hvilket er fint.
Jeg vil så lave en søgning hvor man søger på nogle kriterier (navn og den slags) og så vises der en liste med søgeresultater. I disse søgeresultater skal der så også være en checkbox der siger om et medlem har et gyldigt medlemskab eller ej.

Det lyder jo fint nok, og løsningen kunne være:

SELECT k.nr,k.navn,(select count(m.id) from medlemskab m where k.nr=m.nr and m.slutdato>'2008-07-10') FROM `database`.`kunder` k

Og så hvis count() giver 0, er der ingen medlemskaber!

Men denne query tager en del tid at udføre. Der er noget i nærheden af 4-5000 rækker i hver og søgningen tager omkring 50 sekunder (På en Quad-Core og med masser af ram).

Er der en måde at optimere denne søgning på, ved ikke om det er mig der gør det lidt forkert?
Avatar billede arne_v Ekspert
08. oktober 2008 - 00:33 #1
SELECT k.nr,k.navn,count(m.id)
FROM kunder k,medlemskab m
WHERE k.nr=m.nr AND m.slutdato>'2008-07-10'
GROUP BY k.nr,k.navn

er måske hurtigere.

Derudover: put index på k.nr,k.navn,m.nr og m.slutdato
Avatar billede kjulius Novice
08. oktober 2008 - 19:53 #2
SELECT k.nr, k.navn, CASE WHEN COUNT(m.nr) > 0 THEN 'J' ELSE 'N' END AS Medlemskab
FROM kunder k
LEFT JOIN medlemskab m ON k.nr=m.nr AND m.slutdato>'2008-07-10'
GROUP BY k.nr, k.navn

Ikke meget forskelligt fra den arne_v kom med, men den her vil også vise kunder uden medlemskab (pga. LEFT JOIN).

Rådet om at sætte index på bør du lytte til, det kan gøre den afgørende forskel i hastighed. Man kan måske diskutere om der grund til at sætte index på k.navn, da det jo nok hænger sammen med k.knr i et 1:1 forhold.
Avatar billede arne_v Ekspert
25. oktober 2008 - 23:02 #3
danm ?
Avatar billede danm Nybegynder
11. marts 2009 - 21:25 #4
Beklager det meget sene svar. Jeg fik først kigget på det igen nu her (har gang i for meget kodning på en gang)...

Men det ser ud til jeg helt har overset betydningen af index, og har nu efterhånden ført det på de fleste tabeller der har noget sammenhæng med medlemsnummre eller andre indexer.

Dette har i bund og grund ført til en væsentlig ændring må man sige. Hvis jeg kører den samme sætning som jeg har skrevet i spørgsmålet, foretages søgningen nu på under 1 sek! (0,0374 sek ifølge mysql administrator)

Så index var vist løsningen. Smid endelig et svar arne_v
Avatar billede arne_v Ekspert
11. marts 2009 - 21:39 #5
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
Computerworld tilbyder specialiserede kurser i database-management

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