Einzelnen Beitrag anzeigen

jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#9

AW: SQL Script optimieren damit es schneller geht

  Alt 25. Feb 2017, 01:29
Ich sehe da einen Widerspruch zwischen dem Statement aus #1 und der Anforderung " Ich möchte einfach alle Datensätze aus der Tabelle1 bei den in der Tabelle2 kein Datensatz vorhanden ist bei dem die beiden Feler übereinstimmen."
Der Ansatz mit left outer join ist dabei richtig, aber die Prüfung nur auf "Tabelle2.Status is null " ist unsicher, weil sie -ohne Kenntnis des Datenmodells- auch von sich aus null sein kann. (Außer das ist per constraint verboten)
Sicher wäre die Prüfung auf dem/den Join Feldern selbst, also
Code:
 Left Outer Join Tabelle2 on
      Tabelle1.Staus = Tabelle2.Status
  and Tabelle1.CoNummer = Tabelle2.CoNummer
where Tabelle2.CoNummer is null and Tabelle2.Status is null
Wenn ich mit meinen Vermutung richtig liege, sind auch die beiden Vorschläge aus #6 diesbezüglich nicht ausreichend. Die Null Prüfung auf T2.Status sollte eigentlich auch auf CoNummer laufen und ergibt ihren Sinn erst nach dem Join

Die Fragen nach den Einzelmengen inkl. der einschränkenden Kriterien halte ich auch für sehr wichtig. Sie bieten wichtige Anhaltspunkte, dem Optimizer einen kleinen Tritt zu geben. (Die verwendeten Indizes sehen jedenfalls nicht sehr geschickt gewählt aus)

In der Hoffnung, dass die Menge allein durch den Join stark reduziert wird, würde ich das auch zuerst versuchen. (Nebenbei, keines der anderen gefilterten Felder klingt so, als ob selbst ein vorhandener und verwendeter Index viel nützt. 500T Datensätze mit einer handvoll Statuswerte, da lohnt kein Index)

Also Step 1 sowas:
Code:
SELECT Tabelle1.MasterNummer FROM Tabelle1
  LEFT OUTER JOIN Tabelle2 ON
       Tabelle1.CoNummer = Tabelle2.CoNummer
eigentlich nur, um zu wissen wieviel das wird, also schneller
Code:
SELECT count(*) FROM Tabelle1
  LEFT OUTER JOIN Tabelle2 ON
       Tabelle1.CoNummer = Tabelle2.CoNummer
Step 2 (nun wenigstens mit vollständigem Join Kriterium)
Code:
SELECT Tabelle1.MasterNummer FROM Tabelle1
  LEFT OUTER JOIN Tabelle2 ON
       Tabelle1.CoNummer = Tabelle2.CoNummer
WHERE Tabelle1.Staus = Tabelle2.Status
  and Tabelle2.CoNummer is null
  and Tabelle2.Status is null
Status ins where, um den Optimizer zu lotsen. (Macht besonders Sinn, wenn CoNummer ein (Primär-)Schlüsselfeld ist oder wenigstens Fremdschlüssel und beidseitig indiziert.
Dieses Statement enthält logisch die korrekte Prüfung der Anforderung "alle Datensätze aus der Tabelle1 bei den in der Tabelle2 kein Datensatz vorhanden ist". Dabei beziehe ich mich auf das in #1 verwendete Joinkriterium über 2 Felder.

Wenn das jetzt schneller sein sollte, wird das endgültige Statement hoffentlich nicht langsamer:

Code:
select * from (
       SELECT Tabelle1.MasterNummer, Tabelle1.Status, Tabelle1.Storno FROM Tabelle1
         LEFT OUTER JOIN Tabelle2 ON
              Tabelle1.CoNummer = Tabelle2.CoNummer
        WHERE Tabelle1.Staus = Tabelle2.Status
          and Tabelle2.CoNummer is null
          and Tabelle2.Status is null) x
 where x Status <> 'N' and x.Storno is Null
Die Unterteilung ist des Statements ist geraten hat nur einen Sinn, Optimizer Hilfestellung.

Optimizer Hilfestellung kann man aber auch ganz anders machen.
a) Selber einen Plan angeben
b) Unnütze Indizes löschen, idealerweise bleiben nur die übrig, die verwendet werden sollen

Beides ist ohne Angaben zu Werteverteilung in den Filterfeldern, Datenmodell und zur Verwendung der Felder in anderen Abfragen nicht sinnvoll.
Gruß, Jo

Geändert von jobo (25. Feb 2017 um 01:33 Uhr)
  Mit Zitat antworten Zitat