kleinerheiner: self-join frage

hallo und ein frohes neues jahr!

ich habe eine tabelle mit zwei spalten "id" und "inhalt". es sollen alle "ids" generiert werden, die den "inhalt" A,B und C beinhalten. wie verknüpfe ich am besten die self-joins (mit left join...?)?

id inhalt
1 A
1 C
2 A
2 B
2 C
3 B

vorschlag:

SELECT DISTINCT(t1.id) FROM tabelle AS t1
join tabelle AS t2 on t1.id = t2.id
join tabelle AS t3 on t2.id = t3.id
WHERE t1.inhalt = "A" AND t2.inhalt = "B" AND t3.inhalt = "C" AND

mich irritiert, das je nach dem wie ich die reihenfolge der WHERE-bedingungen gestalte, die abfragezeit ganz stark schwankt, z.b. dauert "WHERE A AND B AND C" viel länger als "WHERE A AND C AND B" usw.

warum?

gruß
heiner

  1. <ÜBERARBEITET>
    nochmal hallo und ein frohes neues jahr!

    ich habe eine tabelle mit zwei spalten "id" und "inhalt". es sollen alle "ids" generiert werden, die den "inhalt" A,B und nicht C beinhalten. wie verknüpfe ich am besten die self-joins (mit left join...?)?

    id inhalt
    1 A
    1 C
    2 A
    2 B
    2 C
    3 B
    3 D

    vorschlag:

    SELECT DISTINCT(t1.id) FROM tabelle AS t1
    join tabelle AS t2 on t1.id = t2.id
    join tabelle AS t3 on t2.id = t3.id
    WHERE t1.inhalt = "A" AND t2.inhalt = "B" AND t3.inhalt != "C"

    mich irritiert, das je nach dem wie ich die reihenfolge der WHERE-bedingungen gestalte, die abfragezeit ganz stark schwankt: wenn ich z.b. t1.inhalt != "C" als erste WHERE-bedingung nehme, ist die abfragedauer viel länger als oben im vorschlag.

    warum?

    gruß
    heiner

    1. Hallo,

      mich irritiert, das je nach dem wie ich die reihenfolge der WHERE-bedingungen gestalte, die abfragezeit ganz stark schwankt: wenn ich z.b. t1.inhalt != "C" als erste WHERE-bedingung nehme, ist die abfragedauer viel länger als oben im vorschlag.

      Drei mögliche Ursachen:
      1.) Joins werden nur für Treffer der Haupttabelle aufgelöst. Sind diese eingeschränkt (t1.inhalt = "A"), so entfällt für die restlichen Datensätze Arbeit für die Datenbank. Wahrscheinlich ist t1 deine 'treibende Tabelle'.

      2.) Gleichheitbedingungen (wie z.B. t1.inhalt = "A") schränken das Ergebnis viel stärker ein als Ungleichheitsbedingungen (t3.inhalt != "C").

      3.) Durch die UND-VErknüfungen der Bedingungen enfallen weitere Prüfungen, wenn die erste schon nicht mehr WAHR ergibt.

      Ich denke der Performance-Unterschied ergibt sich durch ein Zusammenspiel aller drei Faktoren.

      Genaueres findest Du sicherlich in der Dokumentation von Deinem DBMS.

      Andere Datenbankenkönnten allerdings anders arbeiten, da eventuell die treibende Tabelle anders ermittelt wird, oder aber auch die Bedingungen anders abgearbeitet werden. Bei einem Wechsel des DBMS würde eventuell eine Neuformulierung der Statements notwendig sein.

      Grüße
        Klaus

  2. yo,

    wie verknüpfe ich am besten die self-joins (mit left join...?)?

    SELECT DISTINCT id
    FROM tabelle as tab1,tabelle as tab2,tabelle as tab3
    WHERE tab1.id=tab2.id AND tab2.id=tab3.id
    AND tab1.inhalt='A' AND tab2.inhalt='B' AND tab3.inhalt='C';

    Ilja

    1. danke ilja - malwieder ;-) !

      SELECT DISTINCT id
      FROM tabelle as tab1,tabelle as tab2,tabelle as tab3
      WHERE tab1.id=tab2.id AND tab2.id=tab3.id
      AND tab1.inhalt='A' AND tab2.inhalt='B' AND tab3.inhalt!='C';

      aber warum gibt es so starke performance-unterschiede zwischen folgenden bedingungen?
      AND tab1.inhalt='A' AND tab2.inhalt='B' AND tab3.inhalt!='C';
      AND tab1.inhalt!='C' AND tab2.inhalt='B' AND tab3.inhalt='A';

      heiner

      1. yo,

        aber warum gibt es so starke performance-unterschiede zwischen folgenden bedingungen?

        AND tab1.inhalt='A' AND tab2.inhalt='B' AND tab3.inhalt!='C';
        AND tab1.inhalt!='C' AND tab2.inhalt='B' AND tab3.inhalt='A';

        weil er meiner meinung nach der reihe nach vorgeht und je mehr Datensätze man am anfang schon ausschliessen kann, um so weniger arbeit hat man später. mit inhalt = 'A' schließt du im ersten schritt mehr Datensätze aus, als mit inhalt !='C'.

        Ilja

        1. klingt gut, danke. nur ist es praktisch schwierig zu messen, welche where-bedingung die beste ist und welche die schlechteste.

          gruß
          heiner

          1. yo,

            ganz sicher bin ich mir da selbst nicht, aber im zweifelsfalle zeit einfach messen.

            Ilja

  3. Moin!

    ich habe eine tabelle mit zwei spalten "id" und "inhalt". es sollen alle "ids" generiert werden, die den "inhalt" A,B und C beinhalten. wie verknüpfe ich am besten die self-joins (mit left join...?)?

    Kannst du die gewünschte Ausgabe mal in Form einer Tabelle schreiben?

    - Sven Rautenberg

    --
    Die SelfHTML-Developer sagen Dankeschön für aktuell 20885,68 Euro Spendengelder!