left join oder explode ?
am 16.01.2006 13:28:33 von Jan Rademacher
Hallo, heut mal wieder was einfaches/happiges ?!?
Ich habe zwei Systeme, und ich weiss nicht, welches ich nehmen soll (aus
Performancegründen, bzw aus logischen Gründen)
Die erste Version hat eine Tabelle
userid | name | arbeitsweise | verantwortungsgrad |
-------+-------+--------------+---------------------
1 | Hans | |1|3|11|14| | |3|4|6|8|
2 | Fritz | |3|5| | |1|7|12|
ich explode hier die arbweitsweise und den Verantwortungsgrad und suchte
dann mittels
SELECT * FROM JOB
where ( find_in_set('|2|',arbeitsweise ) ||
find_in_set('|4|',arbeitsweise) OR
( find_in_set('|2|',verantwortungsgrad ) ||
find_in_set('|4|',verantwortungsgrad )
das ging nicht. FIND_IN_SET kann leider nur nach einem Element suchen.
dann versuchte ich
SELECT * FROM JOB
where ( arbeitsweise LIKE "%|2|%" || arbeitsweise LIKE "%|4|%" )
OR
( verantwortungsgrad LIKE "%|2|%" || verantwortungsgrad LIKE "%|4|%" )
das klappt wunderbar, nur mache ich mir über die Performance Sorgen,
wenn die Usertabelle auf über 200000 oder nochmehr user wächst...
Bei dem beschriebenen Vorgehen wurde mir dringend geraten auf folgendes
System umzusteigen (leider ohne kompetenten Lösungsweg)
Ich habe eine Usertabelle und mehrere Tabellen mit Eigenschaften
in der die userid und der Wert genannt wird.
user
userid | name
-------+-------
1 | Hans
2 | Fritz
....
arbeitsweise
userid | arbeitsweise
-------+-------------
1 | 2
1 | 5
1 | 9
2 | 2
2 | 4
verantwortungsgrad
userid | verantwortungsgrad
-------+-------------------
1 | 3
1 | 4
1 | 7
2 | 5
2 | 6
Der Query dazu:
SELECT a.userid,a.name,b.arbeitsweise,c.verantwortungsgrad from `user` a
left join `arbeitsweise` b USING(userid)
left join `verantwortungsgrad` c USING(userid)
WHERE ( b.arbeitsweise='1' || b.arbeitsweise='3' )
AND ( c.verantwortungsgrad='1' )
ORDER by name DESC LIMIT 100
In der Ausgabe erscheinen die Namen nur mehrfach, da die userid in den
join Tabellen ja mehrfach vorkommt.
Meine Fragen:
-Was ist performanter ?
-Wie würdet Ihr Euch entscheiden?
-Wenn das zweite System das bessere ist, wie müsste man den Query
basteln, damit man jeden User nur einmal sieht?
DANKE !!!!
--
Jan Rademacher
http://www.lockerbleiben.net
Re: left join oder explode ?
am 16.01.2006 13:32:54 von Dirk Brosowski
Jan Rademacher schrieb:
> Hallo, heut mal wieder was einfaches/happiges ?!?
>
> Ich habe zwei Systeme, und ich weiss nicht, welches ich nehmen soll (aus
> Performancegründen, bzw aus logischen Gründen)
>
> Die erste Version hat eine Tabelle
>
> userid | name | arbeitsweise | verantwortungsgrad |
> -------+-------+--------------+---------------------
> 1 | Hans | |1|3|11|14| | |3|4|6|8|
> 2 | Fritz | |3|5| | |1|7|12|
>
> ich explode hier die arbweitsweise und den Verantwortungsgrad und suchte
> dann mittels
>
> SELECT * FROM JOB
> where ( find_in_set('|2|',arbeitsweise ) ||
> find_in_set('|4|',arbeitsweise) OR
> ( find_in_set('|2|',verantwortungsgrad ) ||
> find_in_set('|4|',verantwortungsgrad )
>
> das ging nicht. FIND_IN_SET kann leider nur nach einem Element suchen.
>
> dann versuchte ich
> SELECT * FROM JOB
> where ( arbeitsweise LIKE "%|2|%" || arbeitsweise LIKE "%|4|%" )
> OR
> ( verantwortungsgrad LIKE "%|2|%" || verantwortungsgrad LIKE "%|4|%" )
>
> das klappt wunderbar, nur mache ich mir über die Performance Sorgen,
> wenn die Usertabelle auf über 200000 oder nochmehr user wächst...
>
>
> Bei dem beschriebenen Vorgehen wurde mir dringend geraten auf folgendes
> System umzusteigen (leider ohne kompetenten Lösungsweg)
>
>
> Ich habe eine Usertabelle und mehrere Tabellen mit Eigenschaften
> in der die userid und der Wert genannt wird.
>
> user
> userid | name
> -------+-------
> 1 | Hans
> 2 | Fritz
> ...
>
> arbeitsweise
> userid | arbeitsweise
> -------+-------------
> 1 | 2
> 1 | 5
> 1 | 9
> 2 | 2
> 2 | 4
>
> verantwortungsgrad
> userid | verantwortungsgrad
> -------+-------------------
> 1 | 3
> 1 | 4
> 1 | 7
> 2 | 5
> 2 | 6
>
> Der Query dazu:
>
> SELECT a.userid,a.name,b.arbeitsweise,c.verantwortungsgrad from `user` a
> left join `arbeitsweise` b USING(userid)
> left join `verantwortungsgrad` c USING(userid)
> WHERE ( b.arbeitsweise='1' || b.arbeitsweise='3' )
> AND ( c.verantwortungsgrad='1' )
> ORDER by name DESC LIMIT 100
>
> In der Ausgabe erscheinen die Namen nur mehrfach, da die userid in den
> join Tabellen ja mehrfach vorkommt.
>
> Meine Fragen:
> -Was ist performanter ?
> -Wie würdet Ihr Euch entscheiden?
> -Wenn das zweite System das bessere ist, wie müsste man den Query
> basteln, damit man jeden User nur einmal sieht?
>
> DANKE !!!!
>
>
Die dritte Frage hat als Antwort "distinct", entscheiden würde ich mich
für die saubere Variante, und das ist ganz klar die zweite. Die
Performace dürfte da auch besser sein.
Grüße
Dirk
Re: left join oder explode ?
am 16.01.2006 13:53:24 von Axel Schwenke
Jan Rademacher wrote:
> Hallo, heut mal wieder was einfaches/happiges ?!?
>
> Ich habe zwei Systeme, und ich weiss nicht, welches ich nehmen soll (aus
> Performancegründen, bzw aus logischen Gründen)
>
> Die erste Version hat eine Tabelle
>
> userid | name | arbeitsweise | verantwortungsgrad |
> -------+-------+--------------+---------------------
> 1 | Hans | |1|3|11|14| | |3|4|6|8|
> 2 | Fritz | |3|5| | |1|7|12|
Bäh. Nicht normalisiert. Nicht machen!
> Bei dem beschriebenen Vorgehen wurde mir dringend geraten auf folgendes
> System umzusteigen (leider ohne kompetenten Lösungsweg)
Was ist ein "kompetenter Lösungsweg"?
[normalisiertes Schema]
> Der Query dazu:
>
> SELECT a.userid,a.name,b.arbeitsweise,c.verantwortungsgrad from `user` a
> left join `arbeitsweise` b USING(userid)
> left join `verantwortungsgrad` c USING(userid)
> WHERE ( b.arbeitsweise='1' || b.arbeitsweise='3' )
> AND ( c.verantwortungsgrad='1' )
> ORDER by name DESC LIMIT 100
Nur so, als Bemerkung: in Perl kann man || und OR weitgehend synonym
verwenden, in SQL nicht.
> In der Ausgabe erscheinen die Namen nur mehrfach, da die userid in den
> join Tabellen ja mehrfach vorkommt.
Vor allem, weil du LEFT JOIN verwendest, wo du eigentlich einen
INNER JOIN haben willst.
SELECT ...
FROM user AS a
JOIN arbeitsweise AS b USING (userid)
JOIN verantwortungsgrad AS c USING (userid)
WHERE b.arbeitsweise IN (1,3)
AND c.verantwortungsgrad = 1
> -Wie würdet Ihr Euch entscheiden?
In Verbindung mit einer relationalen Datenbank natürlich für
das normalisierte Schema.
> -Was ist performanter ?
Mit korrekten Indizes ist das normalisierte Schema schneller.
XL
Re: left join oder explode ?
am 16.01.2006 14:16:30 von Andreas Kretschmer
Andreas
--
Andreas Kretschmer
Linux - weil ich es mir wert bin!
GnuPG-ID 0x3FFF606C http://wwwkeys.de.pgp.net