Anmelden

View Full Version : mal wieder sql performance



Seiten : [1] 2

ILEMax
20-12-17, 10:56
Hallo liebe SQL-Gurus

beide beteiligten Dateien haben rd 8,5 Mio Datensätze
so war es mal:


create table temp#b/zuviel as (
select * from temp#b/meld where trstatus = 'P' and trstat00 <> 'I'
and trstat00 <> 'K'
and (trrmbele, trbv) not in(select s1bunr, s1bvrg from dtpp
where s1stat = 0 and s1kzfb = 1)) with data


das ist die letzte version


select * from temp#b/meld left outer join dtpp on
trrmbele = s1bunr and trbv = s1bvrg where
trstatus = 'P' and trstat00 <> 'I' and trstat00 <> 'K'
and s1stat = 0 and s1kzfb = 1 and s1btyp is null



Ich brauche aus Datei meld die Sätze, die NICHT in DTPP drin sind.

Ich habe alle Versionen durch
With a as ... (einfach, mehrfach)
not exists statt Join
alle empfolenen Indices/LF angelegt (mit und ohne select auf die o.a. selektionen)

Laufzeit immer > 1 Stunde

Das kann doch nicht wirklich richtig ein oder?
Beide Dateien haben KEINE gelöschten Sätze

Hat noch jemand eine Idee die Laufzeit etwas erträglicher zu machen?

Danke
Der ILEMax

Pikachu
20-12-17, 11:15
Probier's doch mal in 3 Etappen:

Jeweils eine Teilmenge der beiden Dateien erstellen und anschließend diese Teilmengen verknüpfen.

Fuerchau
20-12-17, 11:48
Ein Left join schließt ja nun mal nichts aus sondern ergänzt die Daten nur um Zusatzfelder oder NULL falls nix da ist.
Also ist die 1. Version eigentlich so korrket:

select * from temp#b/meld a where trstatus = 'P' and trstat00 <> 'I'
and trstat00 <> 'K'
and not exists (select * from dtpp b where ....)

Für den not exists sind mir die Feldbeziehungen zwischen meld und dtpp nicht klar, also entsprechend anpassen.
Jetzt musst du natürlich bedenken, dass alle Sätze mit P durchsucht werden müssen, da für <> kein Index genommen werden kann.
Und je nach Ergebnis sind da eben viele Zugriffe erforderlich.

BenderD
20-12-17, 12:15
8,5 Mio ist ja nicht gerade viel, die hat man ja in einer Stunde fast mit der Hand durchsucht. Hast Du ma einen exception join probiert? (obwohl ja frei nach Theorie alle Varianten gleich schnell sein sollen.)

D*B

ILEMax
20-12-17, 12:18
Danke,
@Baldur
Die erste Version ist seid ca. 5 Jahren im Einsatz. Aber mit der immer länger werdenden Laufzeit nicht mehr zumutbar

@pikachu

create table temp#b/zuviel as(
with a as (select * from temp#b/meld where trstatus = 'P' and
trstat00 <> 'I' and trstat00 <> 'K'),
b as (select * from dtpp where s1stat=0 and s1kzfb = 1)
select * from a left outer join b on
trrmbele = s1bunr and trbv = s1bvrg where s1btyp is NULL)
with data
läuft seid 40 Minuten ...

ILEMax
20-12-17, 12:21
@DB
exception join ?
nö, ich glaube den kenn ich nicht.

Werde mal googlen und berichten

BenderD
20-12-17, 12:21
... was ich auch schon gehabt habe, war, dass create with no data und insert select eine andere (schnellere) Strategie gewählt hat.

D*B

Fuerchau
20-12-17, 13:13
Exception Join entspricht eigentlich dem "not exists", der später implementiert wurde.

Und ein With-SQL ist nur eine andere Schreibweise. Es wird tatsächlich keine temporäre Tabelle erstellt.
Ich habe aber aus ähnlichen Gründen auch schon mit temporären Tabellen gearbeitet, also in 2 oder auch mehr Schritten selektiert:

create table tempA ... as select ....
create table tempB ... as select * from tempA .....

BenderD
20-12-17, 13:18
... keine CTE! erst Tabelle erstellen und dann in einem weiteren SQL Statement insert into select.

Pikachu
20-12-17, 13:25
Probier's mal mit 3 eigenständigen SELECTs nacheinander...

SELECT ... FROM Datei 1 WHERE ... >> Arbeitsdatei 1
SELECT ... FROM Datei 2 WHERE ... >> Arbeitsdatei 2

SELECT ... FROM Arbeitsdatei 1 WHERE ... NOT IN (
SELECT ... FROM Arbeitsdatei 2)