Abfrageproblem mit einer großen Anzahl von Inner Joins
Abfrageproblem mit einer großen Anzahl von Inner Joins
am 27.02.2007 20:14:52 von xylux
Hallo,
ich habe folgende Abfrage mit einer dynamischen Anzahl von Inner Joins.
Diese werden nach Bedarf mit PHP generiert.
Mit bis zu 9 Joins funktioniert es prima, danach bricht die Performance
drastisch ein.
Bei explain select... steht unter
table: a
type: range
rows: 41
Extras: Using where; Using temporary; Using filesort
Also kann MySql die Abfrage wohl nicht mehr im Arbeitsspeicher bearbeiten.
Es werden 3 Tabellen genutzt
artikel
themen_schl (verknüpft artikel mit themen)
themen
Jedem Artikel können so mehrere Themen zugeordnet werden.
Meine Frage:
Gibt es in MySql 5,0 eine Einschränkung bezüglich der Anzahl der Joins bzw.
wie kann ich die Abfrage (gekürzt) unten besser formulieren / umbauen.
select
GROUP_CONCAT(DISTINCT t.bez ORDER BY bez SEPARATOR ', ') as bez,
kurzform, name_lang, pub_datum, heft_nr
from themen_schl tsA
INNER JOIN themen_schl ts1 ON ts1.id_artikel = a.id
INNER JOIN themen_schl ts2 ON ts2.id_artikel = a.id
INNER JOIN themen_schl ts3 ON ts3.id_artikel = a.id
INNER JOIN themen_schl ts4 ON ts4.id_artikel = a.id
INNER JOIN themen_schl ts5 ON ts5.id_artikel = a.id
INNER JOIN themen_schl ts6 ON ts6.id_artikel = a.id
INNER JOIN themen_schl ts7 ON ts7.id_artikel = a.id
INNER JOIN themen_schl ts8 ON ts8.id_artikel = a.id
INNER JOIN themen_schl ts9 ON ts9.id_artikel = a.id
INNER JOIN themen_schl ts10 ON ts10.id_artikel = a.id
INNER JOIN themen_schl ts11 ON ts11.id_artikel = a.id
INNER JOIN themen_schl ts12 ON ts12.id_artikel = a.id
INNER JOIN themen_schl ts13 ON ts13.id_artikel = a.id
INNER JOIN themen_schl ts14 ON ts14.id_artikel = a.id
INNER JOIN themen_schl ts15 ON ts15.id_artikel = a.id
INNER JOIN themen t ON t.ind_themen = tsA.id_themen
INNER JOIN artikel a ON a.id = tsA.id_artikel
where
( ts1.id_themen=1
or ts2.id_themen=37
or ts3.id_themen=2
or ts4.id_themen=4
or ts5.id_themen=5
or ts6.id_themen=6
or ts7.id_themen=7
or ts8.id_themen=45
or ts9.id_themen=8
or ts10.id_themen=38
or ts11.id_themen=35
or ts12.id_themen=9
or ts13.id_themen=33
or ts14.id_themen=10
or ts15.id_themen=47 )
and pub_datum between '2007-1-27' and '2007-2-27'
GROUP BY a.id
order by t.bez, pub_datum DESC, kurzform DESC
Danke + Gruß
Hans
Re: Abfrageproblem mit einer großenAnzahl vonInner Joins
am 28.02.2007 12:09:44 von Christian Hammers
On 2007-02-27 Hans Rudolf Armgart wrote:
> Hallo,
> ich habe folgende Abfrage mit einer dynamischen Anzahl von Inner Joins.
> Diese werden nach Bedarf mit PHP generiert.
> Mit bis zu 9 Joins funktioniert es prima, danach bricht die Performance
> drastisch ein.
Nur so eine spontane Idee, aber oft vergisst man ja, daß es UNION gibt :)
SELECT
thema
FROM
(
SELECT id, thema FROM ts1 WHERE id=3D4 UNION
SELECT id, thema FROM ts2 WHERE id=3D6 UNION
...
) as x
WHERE
...
tschüss,
-christian-
Re: Abfrageproblem mit einer großenAnzahl von Inner Joins
am 28.02.2007 14:31:27 von Thomas Rachel
Hallo,
Hans Rudolf Armgart wrote:
> select
> GROUP_CONCAT(DISTINCT t.bez ORDER BY bez SEPARATOR ', ') as bez,
> kurzform, name_lang, pub_datum, heft_nr
>
> from themen_schl tsA
>
> INNER JOIN themen_schl ts1 ON ts1.id_artikel = a.id
> INNER JOIN themen_schl ts2 ON ts2.id_artikel = a.id
> INNER JOIN themen_schl ts3 ON ts3.id_artikel = a.id
> INNER JOIN themen_schl ts4 ON ts4.id_artikel = a.id
> INNER JOIN themen_schl ts5 ON ts5.id_artikel = a.id
> INNER JOIN themen_schl ts6 ON ts6.id_artikel = a.id
> INNER JOIN themen_schl ts7 ON ts7.id_artikel = a.id
> INNER JOIN themen_schl ts8 ON ts8.id_artikel = a.id
> INNER JOIN themen_schl ts9 ON ts9.id_artikel = a.id
> INNER JOIN themen_schl ts10 ON ts10.id_artikel = a.id
> INNER JOIN themen_schl ts11 ON ts11.id_artikel = a.id
> INNER JOIN themen_schl ts12 ON ts12.id_artikel = a.id
> INNER JOIN themen_schl ts13 ON ts13.id_artikel = a.id
> INNER JOIN themen_schl ts14 ON ts14.id_artikel = a.id
> INNER JOIN themen_schl ts15 ON ts15.id_artikel = a.id
>
> INNER JOIN themen t ON t.ind_themen = tsA.id_themen
> INNER JOIN artikel a ON a.id = tsA.id_artikel
>
> where
> ( ts1.id_themen=1
> or ts2.id_themen=37
> or ts3.id_themen=2
> or ts4.id_themen=4
> or ts5.id_themen=5
> or ts6.id_themen=6
> or ts7.id_themen=7
> or ts8.id_themen=45
> or ts9.id_themen=8
> or ts10.id_themen=38
> or ts11.id_themen=35
> or ts12.id_themen=9
> or ts13.id_themen=33
> or ts14.id_themen=10
> or ts15.id_themen=47 )
> and pub_datum between '2007-1-27' and '2007-2-27'
> GROUP BY a.id
> order by t.bez, pub_datum DESC, kurzform DESC
Kann sein, daà ich da jetzt komplett auf der Leitung stehe, aber ist es denn
wirklich erforderlich, daà die Tabelle für diese Bedingung 15mal mit sich
selbst verknüpft wird? Soweit ich das sehe nicht (CMIIW).
Für diesen Fall sehe ich eine mögliche Alternativlösung:
> select
> GROUP_CONCAT(DISTINCT t.bez ORDER BY bez SEPARATOR ', ') as bez,
> kurzform, name_lang, pub_datum, heft_nr
>
> from themen_schl tsA
>
> INNER JOIN themen_schl ts_oth ON ts1.id_artikel = a.id
> INNER JOIN themen t ON t.ind_themen = tsA.id_themen
> INNER JOIN artikel a ON a.id = tsA.id_artikel
> where
> ts_oth.id_themen in (1, 37, 2, 4, 5, 6, 7, 45, 8, 38, 35, 9, 33, 10, 47)
> and pub_datum between '2007-1-27' and '2007-2-27'
> GROUP BY a.id
> order by t.bez, pub_datum DESC, kurzform DESC
HTH,
Thomas
--
----+----+----+----+----+----+----+----+----+----+----+----+ ----+----+----+----+
Re: Abfrageproblem mit einer großen Anzahl von Inner Joins
am 01.03.2007 21:10:08 von xylux
"Christian Hammers" schrieb
>Nur so eine spontane Idee, aber oft vergisst man ja, daß es UNION gibt :)
In der Tat.
Ich habe UNION lange nicht mehr benutzt, aber weiter unten eine passende
Lösung gefunden.
Danke und Gruß
Hans
Re: Abfrageproblem mit einer großen Anzahl von Inner Joins
am 01.03.2007 21:13:20 von xylux
"Thomas Rachel" schrieb
Hallo,
> Für diesen Fall sehe ich eine mögliche Alternativlösung:
>> INNER JOIN themen_schl ts_oth ON ts1.id_artikel = a.id
>> INNER JOIN themen t ON t.ind_themen = tsA.id_themen
>> INNER JOIN artikel a ON a.id = tsA.id_artikel
>> where
>> ts_oth.id_themen in (1, 37, 2, 4, 5, 6, 7, 45, 8, 38, 35, 9, 33, 10, 47)
das funktioniert gut.
Danke dir, hat mir geholfen.
Die Konstruktion mit den vielen Joins hatte noch einen anderen Hintergrund.
Eine Frage dazu:
Bei
ts_oth.id_themen in (1, 37, 2, 4, 5, 6, 7, 45, 8, 38, 35, 9, 33, 10, 47)
muss jeweils eine der Bedingungen wahr/erfüllt sein.
Wie formuliere ich dann die Abfrage, wenn alle Bedingungen erfüllt sein
müssen -
also so etwas wie eine AND Verknüpfung.
Ich habe schon gegoogelt/im Handbuch gesucht aber nichts paasendes gefunden.
Gruß
Hans