Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Langsamer Left Outer Join (https://www.delphipraxis.net/96707-langsamer-left-outer-join.html)

Dumpfbacke 29. Jul 2007 15:59

Datenbank: Interbase • Version: 6.01 • Zugriff über: IBX

Langsamer Left Outer Join
 
Hallo Leute,
um eine Ergebnis über mehrere Tabellen zu bekommen benutze ich immer Left Outer Join. Es sind natütlich Indexe auf den entsprechenden Feldern vorhanden.

Wenn ich jedoch zwei Bedingungen angebe, so dauert es immer sehr lange. Lann man hier itws machne ?

Delphi-Quellcode:
Left Ouer Join Tabelle1 on (Tabelle2.ID = Tabelle1.ID1 or Tabelle2.ID = Tabelle1.ID2)
Kann man hier etwas verbessen ?
Die Verknüpfung kann zur ID1 oder ID2 der Tabelle 2 hergestellt sein.

Tanja

Jelly 29. Jul 2007 16:07

Re: Langsamer Left Outer Join
 
Wenn das dein DB-Design ist, dann hast du dort schon ein gravierenden Fehler.
Ein Foreign Key sollte nur auf den Primary Key einer Mastertabelle verweisen, und bestimmt nicht auf entweder Spalte ID1 oder ID2.

mkinzler 29. Jul 2007 16:08

Re: Langsamer Left Outer Join
 
Wie sehen die Idices aus?
Die Bedingung sollte eher
SQL-Code:
Tabelle1.ID = 1Tabelle2.ID or Tabelle1.ID2 = Tabelle2.ID
heißén.

Dumpfbacke 29. Jul 2007 17:07

Re: Langsamer Left Outer Join
 
Zitat:

Zitat von Jelly
Wenn das dein DB-Design ist, dann hast du dort schon ein gravierenden Fehler.
Ein Foreign Key sollte nur auf den Primary Key einer Mastertabelle verweisen, und bestimmt nicht auf entweder Spalte ID1 oder ID2.

Nein einen Fehler habe ich nicht gemacht. In der Tabelle steht je Zeile eine Datensatz mit zwei Enden und die Enden können auch verdreht sein. Immer drehen kann ich auch nicht, dafür gibt es andere Gründe.

Tanja

Dumpfbacke 29. Jul 2007 17:09

Re: Langsamer Left Outer Join
 
Zitat:

Zitat von mkinzler
Wie sehen die Idices aus?
Die Bedingung sollte eher
SQL-Code:
Tabelle1.ID = 1Tabelle2.ID or Tabelle1.ID2 = Tabelle2.ID
heißén.

ID,ID1 und ID2 haben alle einen Index. Gibt es unterschiede was bei dem Vergleich vorne steht ? Das wußte ich auch noch nicht. Werde es gleich mal Test.

Tanja

mkinzler 29. Jul 2007 17:10

Re: Langsamer Left Outer Join
 
Und besitzt dir Tabelle1 jeweils ein Index auf ID1 und ID2?
[Edit:
Zitat:

Gibt es unterschiede was bei dem Vergleich vorne steht ?
U.U dreht das DBMS die Bedingung bei der Optimierung
]

TBx 29. Jul 2007 17:16

Re: Langsamer Left Outer Join
 
Hallo!
Zitat:

Zitat von Dumpfbacke
um eine Ergebnis über mehrere Tabellen zu bekommen benutze ich immer Left Outer Join.

Also, wenn Du wirklich immer mit dem LEFT OUTER JOIN arbeitest, solltest Du Dir dringend die Bedeutung von JOINS angucken

Zitat:

Zitat von Dumpfbacke
Es sind natütlich Indexe auf den entsprechenden Feldern vorhanden.

Es sind nur Indexe in der RIGHT-Table sinnvoll, die LEFT-Table wird ja sowieso kompßlett durchlaufen

Zitat:

Zitat von Dumpfbacke
Wenn ich jedoch zwei Bedingungen angebe, so dauert es immer sehr lange.

Das ist ganz klar, für jede der Bedingungen wird die Mastertabelle komplett durchlaufen und versucht, eine Verbindung zur gejointen Tabelle herzustellen

Zitat:

Zitat von Dumpfbacke
Kann man hier etwas verbessen ?

Bei verwendung des LEFT OUTER JOIN: Nein.
Du solltest überprüfen, ob dieser Join die richtige Wahl ist.
Verrate uns hier doch einmal, was Du erreichen willst, wir helfen Dir gerne weiter.

Merke: Der LEFT OUTER JOIN ist der Performance-Killer schlechthin.

Gruß Thomas

PS: Möchtest Du z.B. alle Datensätze aus TabelleA haben, die eine Entsprechung in TabelleB in FELD2 oder FELD3 haben, so wäre der INNER JOIN das Mittel der Wahl.

hoika 30. Jul 2007 10:49

Re: Langsamer Left Outer Join
 
Hallo,

mehrere Sachen fallen mir ein.

1. zu viele Spaltenb im select
select * ist falsch

2. das OR durch ne union ersetzen

SQL-Code:
select Tabelle2.bla from Tabelle2
Left Outer Join Tabelle1 on (Tabelle2.ID = Tabelle1.ID1)

union

select Tabelle2.bla from Tabelle2
Left Outer Join Tabelle1 on (Tabelle2.ID = Tabelle1.ID2)
Vielleicht reicht jetzt nen normaler join ?

3. den left outer join vermeiden
3.1 not Exists (kommt auf die Tabellenstruktur an)

3.2 inner join (also normaler join)
einen Dummyrecord eintragen, so das der Join immer ein Ergebnis hat

Bsp: Personal -> Personalgruppe
hat eine Person keine Personalgruppe, wird 0 als FK eingetragen
die Tabelle Personalgruppe hat einen Record mit 0, wo z.B. Name leer ist.


4. Das Ergebnis dirch zusätzliche Where-Bedingungen einschränken
(Index dort drauf)


Heiko


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:33 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz