Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi ADS Inner Join = No Go? (https://www.delphipraxis.net/178595-ads-inner-join-%3D-no-go.html)

Union 16. Jan 2014 15:06

Datenbank: ADS • Version: 9 • Zugriff über: ace

ADS Inner Join = No Go?
 
Kann mir jemand erklären, warum diese Query mehr als 100x so langsam ist (47s):
Code:
select lsptext.*
from lscoll
left outer join lspack on lspack.lskopf_id = lscoll.lskopf_id and lspack.colli_nr = lscoll.colli_nr
inner join lsptext on lsptext.lspos_id = lspack.lspos_id and lsptext.position = 25 
     and lsptext.art in ('G1', 'G2', 'G3', 'G4', 'D1', 'D2', 'D3', 'D4', 'D5')
where lscoll.id = :ColliId
wie diese (300ms):

Code:
select lsptext.*
from lscoll
left outer join lspack on lspack.lskopf_id = lscoll.lskopf_id and lspack.colli_nr = lscoll.colli_nr
left outer join lsptext on lsptext.lspos_id = lspack.lspos_id
where lscoll.id = :ColliId
  and lsptext.position = 25
  and lsptext.art in ('G1', 'G2', 'G3', 'G4', 'D1', 'D2', 'D3', 'D4', 'D5')
Logisch und vom Ergebnis sind die gleich. Der Query-Plan hat keine Warnungen, alle zu verbindenden Felder sind indiziert.

sx2008 16. Jan 2014 15:28

AW: ADS Inner Join = No Go?
 
Bei zwei LEFT OUTER JOINS kann die Datenbank selbst wählen in welcher Reihenfolge sie die Joins ausführen möchte.
Obwohl das Ergebnis gleich ist kann die Reihenfolge eine grossen Unterschied bei der Anzahl der Operationen ausmachen.
Siehe auch Matrizen-Kettenmultiplikation
Bei einem OUTER JOIN werden keine Indexe benützt!

Bei einem INNER JOIN und einem LEFT OUTER JOIN wäre es möglich oder wahrscheinlich, dass die Datenbank zuerst den INNER JOIN ausführt und danach den LEFT OUTER JOIN weil sie den Index benützen möchte.
Gut möglich, dass dabei genau der aufwändigere Weg gewählt wird.
Der optimale Weg dürfte datenabhängig sein - es ist gar nicht so einfach den richtigen Weg zu finden.

Hier liest doch ein Entwickler von ADS mit, oder?
Du könnst ja mal eine Datenbank mit Testdaten + deine beiden Queries zusammenstellen damit die Jungs das untersuchen können.

Union 16. Jan 2014 15:57

AW: ADS Inner Join = No Go?
 
Zitat:

Zitat von sx2008 (Beitrag 1243996)
Hier liest doch ein Entwickler von ADS mit, oder?
Du könnst ja mal eine Datenbank mit Testdaten + deine beiden Queries zusammenstellen damit die Jungs das untersuchen können.

Leider ist die Datenbank riesig und auch eben noch auf V9 - aktuell ist wohl 11, aber die Kunden weigern sich einen 5-Stelligen Betrag für's Update (womit sie zu lange gewartet haben) auszugeben. Ich habe auch keine Lust, mir die Datenbank über ein VPN in unseren Testserver zu saugen um dann ggf. festzustellen dass es dort genau so langsam ist.

Das mit dem INNER JOIN hatte ich bisher nicht so verstanden wie Du es beschrieben hast. Aber wenn zuerst z.b. dieser Asudruck ausgewertet würde:
Code:
lsptext.position = 25
Dann erklärt das wohl Einiges. Obwohl der Plan bei allen Joins "Estimated Executions=1" ausweist.

jobo 17. Jan 2014 08:05

AW: ADS Inner Join = No Go?
 
Wenn Du eine schnelle Lösung hast, wo ist das Problem?
Gibt es optimizer hints in ADS?

Ansonsten könnte man die Inner Joins zu einer Verschachtelung umbauen. Innen hohe Einschränkung, außen den Rest oder so..
Stichwort wäre mal wieder die "Selektivität".
Ein Index auf einem Feld, dass nur 2 unterschiedliche Werte, aber Millionen Vorkommen hat ist eigentlich nutzlos. Wenn also formal alles da ist, was die Query braucht, bedeutet das nicht gleich Lichtgeschwindigkeit in der Abfrage.

Falls der Optimizer sowas nicht erkennt, kann das auch an fehlenden oder veralteten Statistiken liegen. Ich weiß aber nicht, wie der bei ADS arbeitet, also ob der Optimizer in der Version überhaupt mit Statistiken arbeitet.

Bspw. unter Oracle 8 gab es den Rule Based Optimizer, der die Ausführungsreihenfolge am Aufbau der Abfrage ausgerichtet hat (From Clause, Where Clause). Da musste man im Zweifel immer selber dran denken, wieviel Daten in welcher Tabelle sind bzw. dann als Abfrageergebnis rauskommen. Vlt ist das hier auch so.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:55 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