Avatar billede mikkelk Nybegynder
24. oktober 2004 - 21:06 Der er 7 kommentarer og
2 løsninger

JOIN og performance-problem

Jeg har følgende sætning:
SELECT billedalbums.titel, billedalbums.beskrivelse, billedalbums.id, billedalbums.type, billedalbums.brugerid, billedalbums.rating, COUNT( DISTINCT billedalbum.id ) AS picCount, AVG( kommentarer.rating ) AS ratings
FROM (
(
(
billedalbums
INNER JOIN billedalbum ON billedalbums.id = billedalbum.albumid
)
INNER JOIN venneliste ON ( billedalbums.brugerid = venneliste.brugerid AND billedalbums.type = 'V' AND venneliste.venid =300 ) OR billedalbums.type = 'A'
)
LEFT JOIN kommentarer ON kommentarer.strID = billedalbums.id AND kommentarer.strtype = 'billedalbum' AND kommentarer.rating <>0
)
GROUP BY billedalbums.id

Problemet er at computeren næsten bliver lagt ned når den eksekveres, på trods af at jeg kun får rækker...

Ved brug af EXPLAIN fås følgende resultat:

http://kongsfelt.dk/joinSQL.jpg

Håber i kan give mig en forklaring og en måde at lave denne forespørgsel på uden at det hele serveren går ned.

MVH Mikkel
Avatar billede mikkelk Nybegynder
24. oktober 2004 - 22:07 #1
Hmm...lidt hjælp :-) Kunne forestille mig at det er nogle index der skal sættes, men hvilke?
Avatar billede majkat Nybegynder
25. oktober 2004 - 07:28 #2
Den store synder er at venneliste ikke bruges optimalt - din explain viser, at MYSQL potentielt skal gennemløbe små 2mio kombinationer hver gang du laver din forespørgsel.

Jeg er ikke sikker, men jeg tror dine paranteser måske forhindrer MySQL's optimizer i at fungere korrekt. Det er heller ikke normalt at lægge sine WHERE ting ind i JOIN betingelserne.

Prøv evt. med nedenstående omskrivning af FROM... og fremefter:

FROM billedalbums, billedalbum, venneliste
    LEFT JOIN kommentarer ON kommentarer.strID = billedalbums.id
WHERE billedalbums.id = billedalbum.albumid
  AND ((billedalbums.brugerid = venneliste.brugerid
        AND billedalbums.type = 'V'
        AND venneliste.venid =300
      )
      OR (billedalbums.type = 'A')
      )
  AND kommentarer.strtype = 'billedalbum'
  AND kommentarer.rating <>0
GROUP BY billedalbums.id
Avatar billede mikkelk Nybegynder
25. oktober 2004 - 19:43 #3
Hmm...virker ummidelbart, men der er et problem. Nemlig at den kun tager de records med hvor der faktisk er en tilhørende record i kommentarer...den skulle helst have alle med også selvom der ikke var en kommentar...
Avatar billede mikkelk Nybegynder
25. oktober 2004 - 20:01 #4
Det her virker, men igen er nogle WHERE ting jo placeret i en JOIN betingelse - og det trækker igen hårdt på serveren(om end ikke helt så hårdt som før...):

SELECT billedalbums.titel, billedalbums.beskrivelse, billedalbums.id, billedalbums.type, billedalbums.brugerid, billedalbums.rating, COUNT( DISTINCT billedalbum.id ) AS picCount, AVG( kommentarer.rating ) AS ratings
FROM billedalbums, billedalbum, venneliste
LEFT JOIN kommentarer ON kommentarer.strID = billedalbums.id AND kommentarer.strtype = 'billedalbum' AND kommentarer.rating <>0
WHERE (
billedalbums.id = billedalbum.albumid AND (
(
billedalbums.brugerid = venneliste.brugerid AND billedalbums.type = 'V' AND (
venneliste.venid =300 OR venneliste.brugerid =300
)
) OR (
billedalbums.type = 'A'
)
)
)
GROUP BY billedalbums.id
Avatar billede majkat Nybegynder
25. oktober 2004 - 22:31 #5
Dette er et rent gæt (det er ved at være sent) - har du prøvet:

FROM (billedalbums, billedalbum, venneliste)
    LEFT JOIN kommentarer ON kommentarer.strID = billedalbums.id
WHERE billedalbums.id = billedalbum.albumid
  AND ((billedalbums.brugerid = venneliste.brugerid
        AND billedalbums.type = 'V'
        AND venneliste.venid =300
      )
      OR (billedalbums.type = 'A')
      )
  AND kommentarer.strtype = 'billedalbum'
  AND kommentarer.rating <>0
GROUP BY billedalbums.id

altså mit oprindelige forslag, bare med parenteser omkring de tre første komma-joinede tabeller?
Avatar billede mikkelk Nybegynder
26. oktober 2004 - 17:16 #6
Den udelader desværre stadigvæk de records hvor der ikke er tilhørende kommentarer...
Avatar billede majkat Nybegynder
26. oktober 2004 - 20:01 #7
Selv efter at have set på det mange gange kan jeg ikke komme på noget der giver dig resultatet i eet hug. Tror du må over i noget med en temporære tabeller til at holde på din avg(rating) beregning og så bruge denne i din LEFT JOIN.
Avatar billede mikkelk Nybegynder
04. november 2004 - 21:15 #8
Takker for hjælpen. Hvis du vil have point for dit besvær, selvom det ikke gav en løsning, så smid et svar så får du halvdelen.
Avatar billede majkat Nybegynder
04. november 2004 - 21:41 #9
ok - tak
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