|
| SQL: JOIN vs. GROUP Fra : Michael Hansen |
Dato : 16-09-04 15:17 |
|
Hej,
Jeg har et lille problem som jeg håber i kan hjælpe mig med.
I mit forum system har jeg 2 tabeller, en med ca 2000 brugere og en anden
med ca 30000 indlæg.
For hver post i indlægs-tabellen er der en henvisning til den bruger der
oprettede indlæget.
Jeg vil nu gerne lave en liste over alle brugere og for hver bruger vise
hvor mange indlæg han har skrevet. Jeg har brugt følgende SQL:
SELECT b.id, b.dato, b.bnavn, b.email, COUNT(i.brugerID) AS antal
FROM brugere b
LEFT JOIN indlag i
ON (b.id = i.brugerID)
WHERE bnavn LIKE 'a%'
GROUP BY b.id
ORDER BY b.id ASC
Det virker efter hensigten, men er utrolig tidskrævende og tager flere
minutter !!
Nedenstående SQL er meget hurtigere men viser KUN de brugere der har 1 eller
flere indlæg.
SELECT b.id, b.dato, b.bnavn, b.email, COUNT(*) AS antal
FROM brugere b, indlag i
WHERE b.id = i.brugerID
AND bnavn LIKE 'a%'
GROUP BY b.id
ORDER BY b.id ASC
Nogen der ved hvordan jeg løser problemet ?
--
Mvh
Michael Hansen
Golf2.dk
| |
Peter Lykkegaard (16-09-2004)
| Kommentar Fra : Peter Lykkegaard |
Dato : 16-09-04 15:57 |
|
"Michael Hansen" wrote
>
> Jeg har et lille problem som jeg håber i kan hjælpe mig med.
> I mit forum system har jeg 2 tabeller, en med ca 2000 brugere og en anden
> med ca 30000 indlæg.
> For hver post i indlægs-tabellen er der en henvisning til den bruger der
> oprettede indlæget.
>
> Jeg vil nu gerne lave en liste over alle brugere og for hver bruger vise
> hvor mange indlæg han har skrevet. Jeg har brugt følgende
Kan du bruge subselects?
Hvilken databasesystem har du adgang til?
- Peter
| |
Michael Hansen (16-09-2004)
| Kommentar Fra : Michael Hansen |
Dato : 16-09-04 16:03 |
|
> > Jeg vil nu gerne lave en liste over alle brugere og for hver bruger vise
> > hvor mange indlæg han har skrevet. Jeg har brugt følgende
>
> Kan du bruge subselects?
> Hvilken databasesystem har du adgang til?
Jeg bruger MySQL.
Hmm ja subselect kan måske godt bruges, men kan ikke selv lige se hvordan.
Har du et forslag ?
--
Mvh
Michael Hansen
Golf2.dk
| |
Peter Lykkegaard (16-09-2004)
| Kommentar Fra : Peter Lykkegaard |
Dato : 16-09-04 19:06 |
|
"Michael Hansen" wrote
> Hmm ja subselect kan måske godt bruges, men kan ikke selv lige se hvordan.
> Har du et forslag ?
SELECT b.id, b.dato, b.bnavn, b.email,
(Select Count(*) from indlag i where b.id = i.brugerid) as Antal
FROM brugere b
WHERE bnavn LIKE 'a%'
PS: Check evt om du har index på brugere.bnavn og indlag.brugerid
- Peter
| |
///JJ (16-09-2004)
| Kommentar Fra : ///JJ |
Dato : 16-09-04 18:21 |
|
Michael Hansen wrote:
> Hej,
> SELECT b.id, b.dato, b.bnavn, b.email, COUNT(i.brugerID) AS antal
> FROM brugere b
> LEFT JOIN indlag i
> ON (b.id = i.brugerID)
> WHERE bnavn LIKE 'a%'
> GROUP BY b.id
> ORDER BY b.id ASC
>
> SELECT b.id, b.dato, b.bnavn, b.email, COUNT(*) AS antal
> FROM brugere b, indlag i
> WHERE b.id = i.brugerID
> AND bnavn LIKE 'a%'
> GROUP BY b.id
> ORDER BY b.id ASC
>
Er jeg helt galt på den, hvis jeg nu siger at det nederste indlæg også er
(el. resulterer i) en join, men bare en inner join - og at det er derfor du
kun får det ønskede resultat i den øverste?
Mvh
///JJ
| |
Michael Hansen (16-09-2004)
| Kommentar Fra : Michael Hansen |
Dato : 16-09-04 18:37 |
|
> Er jeg helt galt på den, hvis jeg nu siger at det nederste indlæg også er
> (el. resulterer i) en join, men bare en inner join - og at det er derfor
du
> kun får det ønskede resultat i den øverste?
>
Jo det kan man vel godt kalde det. Også derfor jeg bruger LEFT JOIN i det
øverste eksempel, så jeg får ALLE rækker fra bruger-tabellen med i
resultatet. Problemet er bare at den er MEGET langsom når den skal tygge sig
igennem 30000 rækker i indlæg-tabellen.
Men hvis der var en eller anden måde man kunne bruge LEFT i en GROUP ??
Som det er nu så viser den KUN de rækker fra bruger-tabellen der har en
eller flere rækker i indlæg-tabellen...
--
Mvh
Michael Hansen
Golf2.dk
| |
Peter Brodersen (16-09-2004)
| Kommentar Fra : Peter Brodersen |
Dato : 16-09-04 18:40 |
|
On Thu, 16 Sep 2004 19:36:30 +0200, "Michael Hansen"
<michael@amweb.dk> wrote:
>Jo det kan man vel godt kalde det. Også derfor jeg bruger LEFT JOIN i det
>øverste eksempel, så jeg får ALLE rækker fra bruger-tabellen med i
>resultatet. Problemet er bare at den er MEGET langsom når den skal tygge sig
>igennem 30000 rækker i indlæg-tabellen.
Er der index på i.brugerID-feltet?
Det kunne godt tyde på, at der ikke var, og den nederste query også
var uoptimal, men dog hurtigere, fordi antallet af rows i "brugere"
blev begrænset hurtigt.
Prøv at afvikle:
EXPLAIN
SELECT b.id, b.dato, b.bnavn, b.email, COUNT(i.brugerID) AS antal
FROM brugere b
LEFT JOIN indlag i
ON (b.id = i.brugerID)
WHERE bnavn LIKE 'a%'
GROUP BY b.id
ORDER BY b.id ASC
... og giv os resultatet.
--
- Peter Brodersen
Ugens sprogtip: terrasse (og ikke terasse)
| |
Peter Brodersen (16-09-2004)
| Kommentar Fra : Peter Brodersen |
Dato : 16-09-04 18:43 |
|
On Thu, 16 Sep 2004 19:39:47 +0200, Peter Brodersen <usenet@ter.dk>
wrote:
>Det kunne godt tyde på, at der ikke var, og den nederste query også
>var uoptimal, men dog hurtigere, fordi antallet af rows i "brugere"
>blev begrænset hurtigt.
Hm, glem den del, i begge tilfælde vil "brugere"-tabellen blive
begrænset hurtigt.
Kør alligevel den EXPLAIN, og lad os se om der er forskel på de to
eksempler.
--
- Peter Brodersen
Ugens sprogtip: terrasse (og ikke terasse)
| |
Michael Hansen (16-09-2004)
| Kommentar Fra : Michael Hansen |
Dato : 16-09-04 18:58 |
|
Sådan !!
Peter du kan sq dit kram !
Der var ikke indeks på brugerID, så det er der nu kommet og så går det sq
hurtigt !
Hvordan er det reglerne er for hvad der skal have indeks og hvad der ikke
skal ?
--
Mvh
Michael Hansen
Golf2.dk
"Peter Brodersen" <usenet@ter.dk> skrev i en meddelelse
news:cicja5$10c$2@katie.ellegaard.dk...
> On Thu, 16 Sep 2004 19:39:47 +0200, Peter Brodersen <usenet@ter.dk>
> wrote:
>
> >Det kunne godt tyde på, at der ikke var, og den nederste query også
> >var uoptimal, men dog hurtigere, fordi antallet af rows i "brugere"
> >blev begrænset hurtigt.
>
> Hm, glem den del, i begge tilfælde vil "brugere"-tabellen blive
> begrænset hurtigt.
>
> Kør alligevel den EXPLAIN, og lad os se om der er forskel på de to
> eksempler.
>
> --
> - Peter Brodersen
>
> Ugens sprogtip: terrasse (og ikke terasse)
| |
Peter Lykkegaard (16-09-2004)
| Kommentar Fra : Peter Lykkegaard |
Dato : 16-09-04 21:52 |
|
"Michael Hansen" wrote
> Hvordan er det reglerne er for hvad der skal have indeks og hvad der ikke
> skal ?
>
Som udgangspunkt så skal du bruge indexes hvor du har en whereclause
I joins ligger der jo også en whereclause
Men det er pest eller kolera da (for) mange indexes alt andet lige sløver
ved opdatering af data i tabellen
- Peter
| |
|
|