Announcement

Collapse
No announcement yet.

SQL beschleunigen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • SQL beschleunigen

    Hallo zusammen
    habe folgenden SQL:
    Code:
       SELECT p.ID, p.PersonalNr, p.Name, p.Vorname, IFNULL(pz.Resturlaubgesamt, 0) as RUL, 
    a.Bezeichnung as Abteilung, a.InterneNummer as AbtNr, f.Bezeichnung as Firma, f.FirmenNr,
    mr.JAHR, mr.MONAT, IFNULL(ZMIF.MinToIHour(mr.SOLLSTUNDEN - mr.KRANKSTUNDENBEZAHLT - mr.URLAUBSSTUNDENBEZAHLT - mr.FEIERTAGSSTUNDEN),0) as SOLL,
    IFNULL(ZMIF.MinToIHour(mr.MO_GLEIT),0) as MGLZ, IFNULL(ZMIF.MinToIHour(mr.AUSBEZAHLT),0) as Ausbezahlt, 
    IFNULL(ZMIF.MinToIHour(mr.JAHRESGLEITZEIT),0) as JGLZ, IFNULL(mr.KAPPUNGSKMONATS_GL,0) as MKappGLZ,
    IFNULL(mr.KAPPUNGSKJAHRES_GL,0) as JKappGLZ, IFNULL(mr.URLAUBSTAGEBEZAHLT,0)  as UL, 
    IFNULL(mr.KRANKENTAGEBEZAHLT,0) as KGA, IFNULL(mr.KRANKENTAGEUNBEZAHLT,0)  as KGU, 
    IFNULL(mr.DIENSTREISE,0) as SDR, IFNULL(mr.BERUFSSCHULE,0) as SBS, 
    IFNULL(ZMIF.MinToIHour(mr.ISTSTUNDENBRUTTO),0) as Brutto, 
    IFNULL(ZMIF.MinToIHour(mr.ISTSTUNDENNETTO),0) as Netto, 
    IFNULL(mr.FEIER_TAGE,0) as FT,
    IFNULL(ZMIF.MinToIHour(e_100.M),0) as Nachtzuschlag,
    IFNULL(ZMIF.MinToIHour(e_110.M),0) as Samstagzuschlag,
    IFNULL(ZMIF.MinToIHour(e_120.M),0) as Sonntagzuschlag,
    IFNULL(ZMIF.MinToIHour(e_130.M),0) as Feiertagzuschlag,
    ZMIF.MinToIHour(IFNULL(sum(b_AR.BSumme),0)) as AR,
    ZMIF.MinToIHour(IFNULL(sum(b_PR.BSumme),0)) as PR,
    ZMIF.MinToIHour(IFNULL(sum(b_AZK.BSumme),0)) as AZK,
    ZMIF.MinToIHour(IFNULL(sum(b_HOM.BSumme),0)) as HOM,
    Count(bd.Fehltag) as Fehltage
    FROM
    Personal p
    LEFT OUTER JOIN Firma f ON p.ID_Firma = f.ID 
    LEFT OUTER JOIN Abteilungen a ON p.ID_Abteilungen = a.ID 
    LEFT OUTER JOIN Monatswerte_Report mr ON p.ID = mr.ID_PERSONAL 
    LEFT OUTER JOIN PersonalZusatz pz ON p.ID = pz.ID_Personal
    LEFT OUTER JOIN Ergebnis e_100 
    	 	   		ON (mr.ID_Personal = e_100.ID_Personal AND e_100.Jahr = mr.Jahr 
       				AND e_100.Monat = mr.Monat AND e_100.Kontonr = 100)
    LEFT OUTER JOIN Ergebnis e_110 
    	 	   		ON (mr.ID_Personal = e_110.ID_Personal AND e_110.Jahr = mr.Jahr 
    				AND e_110.Monat = mr.Monat AND e_110.Kontonr = 110)
    LEFT OUTER JOIN Ergebnis e_120 
    	 	   		ON (mr.ID_Personal = e_120.ID_Personal AND e_120.Jahr = mr.Jahr 
    				AND e_120.Monat = mr.Monat AND e_120.Kontonr = 120)
    LEFT OUTER JOIN Ergebnis e_130 
    	 	   		ON (mr.ID_Personal = e_130.ID_Personal AND e_130.Jahr = mr.Jahr 
    				AND e_130.Monat = mr.Monat AND e_130.Kontonr = 130)
    LEFT OUTER JOIN Buchungen b_AR 
    	 	   		ON (mr.ID_Personal = b_AR.ID_Personal AND Year(b_AR.Datum) = mr.Jahr 
    				AND Month(b_AR.Datum) = mr.Monat and b_AR.Buchungsart = 'AR')
    LEFT OUTER JOIN Buchungen b_PR 
    	 	   		ON (mr.ID_Personal = b_PR.ID_Personal AND Year(b_PR.Datum) = mr.Jahr 
    				AND Month(b_PR.Datum) = mr.Monat and b_PR.Buchungsart = 'PR')
    LEFT OUTER JOIN Buchungen b_AZK 
    	 	   		ON (mr.ID_Personal = b_AZK.ID_Personal AND Year(b_AZK.Datum) = mr.Jahr 
    				AND Month(b_AZK.Datum) = mr.Monat and b_AZK.Buchungsart = 'AZK')
    LEFT OUTER JOIN Buchungen b_HOM 
    	 	   		ON (mr.ID_Personal = b_HOM.ID_Personal AND Year(b_HOM.Datum) = mr.Jahr 
    				AND Month(b_HOM.Datum) = mr.Monat and b_HOM.Buchungsart = 'HOM')
    LEFT OUTER JOIN Buchungsdatei bd ON (mr.ID_Personal = bd.ID_Personal and Year(bd.Datum) = mr.Jahr 
    				AND Month(bd.Datum) = mr.Monat and Fehltag <> '' and Fehltag <> 'UL' 
    				and Fehltag <> 'FT' and Fehltag <> 'KGA' and Fehltag <> 'KGU')
    GROUP BY 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29
    Der SQL dauert vieeeel zu lang, beim Testen im Data Architect stürzt mir dieser sogar immer ab.
    Mir ist aufgefallen dass die LEFT JOINS der Buchungsdatei und vorallem die JOINS der Tabelle Buchungen den SQL extrem verlangsamen.
    Lasse ich diese JOINS weg, wird mein SQL in 1ner Sekunde ausgeführt:
    Code:
    SELECT p.ID, p.PersonalNr, p.Name, p.Vorname, IFNULL(pz.Resturlaubgesamt, 0) as RUL, 
    a.Bezeichnung as Abteilung, a.InterneNummer as AbtNr, f.Bezeichnung as Firma, f.FirmenNr,
    mr.JAHR, mr.MONAT, IFNULL(ZMIF.MinToIHour(mr.SOLLSTUNDEN - mr.KRANKSTUNDENBEZAHLT - mr.URLAUBSSTUNDENBEZAHLT - mr.FEIERTAGSSTUNDEN),0) as SOLL,
    IFNULL(ZMIF.MinToIHour(mr.MO_GLEIT),0) as MGLZ, IFNULL(ZMIF.MinToIHour(mr.AUSBEZAHLT),0) as Ausbezahlt, 
    IFNULL(ZMIF.MinToIHour(mr.JAHRESGLEITZEIT),0) as JGLZ, IFNULL(mr.KAPPUNGSKMONATS_GL,0) as MKappGLZ,
    IFNULL(mr.KAPPUNGSKJAHRES_GL,0) as JKappGLZ, IFNULL(mr.URLAUBSTAGEBEZAHLT,0)  as UL, 
    IFNULL(mr.KRANKENTAGEBEZAHLT,0) as KGA, IFNULL(mr.KRANKENTAGEUNBEZAHLT,0)  as KGU, 
    IFNULL(mr.DIENSTREISE,0) as SDR, IFNULL(mr.BERUFSSCHULE,0) as SBS, 
    IFNULL(ZMIF.MinToIHour(mr.ISTSTUNDENBRUTTO),0) as Brutto, 
    IFNULL(ZMIF.MinToIHour(mr.ISTSTUNDENNETTO),0) as Netto, 
    IFNULL(mr.FEIER_TAGE,0) as FT,
    IFNULL(ZMIF.MinToIHour(e_100.M),0) as Nachtzuschlag,
    IFNULL(ZMIF.MinToIHour(e_110.M),0) as Samstagzuschlag,
    IFNULL(ZMIF.MinToIHour(e_120.M),0) as Sonntagzuschlag,
    IFNULL(ZMIF.MinToIHour(e_130.M),0) as Feiertagzuschlag
    FROM
    Personal p
    LEFT OUTER JOIN Firma f ON p.ID_Firma = f.ID 
    LEFT OUTER JOIN Abteilungen a ON p.ID_Abteilungen = a.ID 
    LEFT OUTER JOIN Monatswerte_Report mr ON p.ID = mr.ID_PERSONAL 
    LEFT OUTER JOIN PersonalZusatz pz ON p.ID = pz.ID_Personal
    LEFT OUTER JOIN Ergebnis e_100 
    	 	   		ON (mr.ID_Personal = e_100.ID_Personal AND e_100.Jahr = mr.Jahr 
       				AND e_100.Monat = mr.Monat AND e_100.Kontonr = 100)
    LEFT OUTER JOIN Ergebnis e_110 
    	 	   		ON (mr.ID_Personal = e_110.ID_Personal AND e_110.Jahr = mr.Jahr 
    				AND e_110.Monat = mr.Monat AND e_110.Kontonr = 110)
    LEFT OUTER JOIN Ergebnis e_120 
    	 	   		ON (mr.ID_Personal = e_120.ID_Personal AND e_120.Jahr = mr.Jahr 
    				AND e_120.Monat = mr.Monat AND e_120.Kontonr = 120)
    LEFT OUTER JOIN Ergebnis e_130 
    	 	   		ON (mr.ID_Personal = e_130.ID_Personal AND e_130.Jahr = mr.Jahr 
    				AND e_130.Monat = mr.Monat AND e_130.Kontonr = 130)
    GROUP BY 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29
    Hab schon probiert, das ganze in einen View auszulagern und über folgenden Select Befehl meine Daten zu erfassen:
    Code:
    SELECT * FROM Vi_KD_MonatsberichtRB
    ###WHERE### 
    ORDER BY 8 desc, 7, 6, 2, 3, 1
    Hat jemand einen Tipp für mich, wie ich meinen SQL perfomanter machen kann?
    Reihenfolge der JOINS, oder JOINS anderst aufbauen?

  • #2
    Hallo Metallicpeace ;-)

    hast Du Dir schon den Execution Plan Deines SQL Statements angeschaut?
    Das hilft oft weiter, Schwachstellen zu erkennen.

    Uli

    P.S. Den Execution Plan kannst Du Dir im ADS im SQL-Fenster, rechte Maustaste und "Show Plan" anzeigen lassen.
    P.P.S. Welche ADS-Version hast Du?

    Comment


    • #3
      Eine Beschleunigung wird auf jeden Fall dann erreicht, wenn für alle Spalten bzw. Kombinationen, die wiederholt verwendet werden, ein Index festgelegt ist. Das sollte auf jeden Fall für alle ON-Bedingungen erfüllt sein.

      Soweit du die ganzen Zusatztabellen (d.h. die Wiederholungen von Ergebnis und Buchungen) nur für jeweils eine Spalte benötigst, könnte es auch etwas bringen, das als Unterabfrage in die Spaltenliste aufzunehmen. Aber das kann besser über den Ausführungsplan geklärt werden. Jürgen

      Comment

      Working...
      X