AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

SQL Sauert zu lange

Ein Thema von Dumpfbacke · begonnen am 23. Jun 2016 · letzter Beitrag vom 23. Jun 2016
Antwort Antwort
Seite 2 von 2     12   
nahpets
(Gast)

n/a Beiträge
 
#1

AW: SQL Sauert zu lange

  Alt 23. Jun 2016, 08:39
and SLAVE.ZusatzStatus in ('EZ','EV','EF','EA','EQ','EP')
Ich bin kein Firebird Spezialist, aber "in ()" oder "or" wird doch sehr wahrscheinlich intern gleich abgearbeitet? Wäre also nur besser für die Augen.
Das mag durchaus so sein, aber durch erhöhte Lesbarkeit hab' ich in der Vergangenheit schon des Öftern fachliche Fehler finden können, die ansonsten nicht auffielen. Gerade bei vielen and und or kann es schonmal schnell passieren, das eine Klammerung knapp daneben ging, auch wenn das Statement syntaktisch weiterhin korrekt war.
Und so knapp daneben liegende Klammern können schonmal schnell zu einer exorbitant steigenden Laufzeit führen.

Und letztlich resultieren meine Fragen zum "threadauslösenden" SQL ja auch daher.

Geändert von nahpets (23. Jun 2016 um 12:54 Uhr) Grund: Schreibfehler behoben
  Mit Zitat antworten Zitat
Benutzerbild von ibp
ibp

Registriert seit: 31. Mär 2004
Ort: Frankfurt am Main
1.511 Beiträge
 
Delphi 7 Architect
 
#2

AW: SQL Sauert zu lange

  Alt 23. Jun 2016, 08:56
...
Wenn ich das ganze ohne die letzte Zeile mache mache dauert es ca. 2 Sekunden. Mit dieser Bedingung dauert es ca. 22 Sekunden.
Wie lange dauert es denn, wenn du die Abfrage nur mit der letzten Bedingung (Zeile) absendest?

SQL-Code:
from MASTER
Left Outer JOIN SLAVE on MASTER.Vorgangsnummer = SLAVE.Vorgangsnummer and (SLAVE.ZusatzStatus = 'EZor SLAVE.ZusatzStatus = 'EVor
                                                                    SLAVE.ZusatzStatus = 'EFor SLAVE.ZusatzStatus = 'EAor
                                                                    SLAVE.ZusatzStatus = 'EQor SLAVE.ZusatzStatus = 'EP')
Left Outer Join MASTER UrMaster on MASTER.Vorgangursprung = UrMaster.Vorgangsnummer
where (UrMaster.referenznr = 'ABT_25' )
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#3

AW: SQL dauert zu lange

  Alt 23. Jun 2016, 09:23
...
Wenn ich das ganze ohne die letzte Zeile mache mache dauert es ca. 2 Sekunden. Mit dieser Bedingung dauert es ca. 22 Sekunden.
Wie lange dauert es denn, wenn du die Abfrage nur mit der letzten Bedingung (Zeile) absendest?
SQL-Code:
from MASTER
Left Outer JOIN SLAVE on MASTER.Vorgangsnummer = SLAVE.Vorgangsnummer and (SLAVE.ZusatzStatus = 'EZor SLAVE.ZusatzStatus = 'EVor
                                                                    SLAVE.ZusatzStatus = 'EFor SLAVE.ZusatzStatus = 'EAor
                                                                    SLAVE.ZusatzStatus = 'EQor SLAVE.ZusatzStatus = 'EP')
Left Outer Join MASTER UrMaster on MASTER.Vorgangursprung = UrMaster.Vorgangsnummer
where (UrMaster.referenznr = 'ABT_25' )
Das dürfte aber zu einem vollständig anderen Ergebnis führen, da die Abfrage auf die ReferenzNr ja nur ein Teil innerhalb der letzten AND-Bedingung ist. Diese Bedingung wird ja nur auf eine bereits erstellte Teilmenge angewandt und nicht auf die Ursprungstabelle. Von daher könnte ich mir vorstellen, dass dort die Nutzung des Index für die Datenbank nicht mehr möglich ist.

Eventuell könnte es aber hilfreich sein, im zweiten Left-Join grundsätzlich auf UrMaster.referenznr <> 'ABT_25' einzuschränken und in einem dritten Left-Join nur die Besonderheiten von UrMaster.referenznr = 'ABT_25' "abzuarbeiten".
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#4

AW: SQL Sauert zu lange

  Alt 23. Jun 2016, 10:30
Wenn man die Datenbank kennen würde, könnte man viel mehr dazu sagen. z.b. diese Slave.ZusatzStatus= or Slave.Zusatzstatus= Orgie, könnte die nicht durch Slave.ZusatzStatus<>x and Slave.Zusatzstatus<>y ersetzt werden?
U.U. kann man 'ABT_25' auch durch eine liste von IDs ersetzen (anderer Index)?
Und dieses
Code:
 SLAVE.SlaveStatus = 'In Arbeit' and SLAVE.Dzusatz is NULL) or
      (SLAVE.SlaveStatus = 'In Abreit' and SLAVE.Dzusatz = 'Gesperrt'
würde ich durch SLAVE.SlaveStatus = 'In Arbeitand (SLAVE.Dzusatz is NULL or SLAVE.Dzusatz = 'Gesperrt') ersetzen.

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Dumpfbacke

Registriert seit: 10. Mär 2005
Ort: Mitten in Deutschland
335 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#5

AW: SQL Sauert zu lange

  Alt 23. Jun 2016, 12:36
...
Wenn ich das ganze ohne die letzte Zeile mache mache dauert es ca. 2 Sekunden. Mit dieser Bedingung dauert es ca. 22 Sekunden.
Wie lange dauert es denn, wenn du die Abfrage nur mit der letzten Bedingung (Zeile) absendest?

[/CODE]
Das führt natürlich zum falschen Ergebnis. Es hat in Summe ganze 15 Minuten benötigt
Tanja

Geändert von Dumpfbacke (23. Jun 2016 um 13:25 Uhr)
  Mit Zitat antworten Zitat
jobo

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

AW: SQL Sauert zu lange

  Alt 23. Jun 2016, 12:57
Zu Ergebnis = 48 Stück.

Ich weiß nicht, wie der Optimizer von FB tickt. Aber ich würde versuchen, ihm zu helfen und folgende Strategie anwenden:
Die Kriterien, die die heftigste Einschränkung liefern für ein Kern-Select-Statement verwenden. (Das sind vielleicht bereits die bloßen Joins) Sodass ein grobes Ergebnis auf weniger als 5000 Datensätze kommt, darf auch weniger sein.
Auf dem Rest dann den ganzen Schnickschnack mit like '%' Or / in () usw. Mglw. geht das, wenn man das Kernselect klammert und außen dann die restlichen Kriterien abfragt.

So ungefähr (vorschlag):
Delphi-Quellcode:
select *
  from (
        select *
          from MASTER
          Left Outer JOIN SLAVE
            on MASTER.Vorgangsnummer = SLAVE.Vorgangsnummer
           and (SLAVE.ZusatzStatus = 'EZor SLAVE.ZusatzStatus = 'EVor
               SLAVE.ZusatzStatus = 'EFor SLAVE.ZusatzStatus = 'EAor
               SLAVE.ZusatzStatus = 'EQor SLAVE.ZusatzStatus = 'EP')
          Left Outer Join MASTER UrMaster
            on MASTER.Vorgangursprung = UrMaster.Vorgangsnummer
         where MASTER.Status = 'In Bearbeitung'
           and SLAVE.SlaveNummerr is not NULL
           and ((SLAVE.SlaveStatus = 'Wartenor
               SLAVE.SlaveStatus = 'Unterbrochenor
               SLAVE.SlaveStatus = 'In Arbeitand SLAVE.Dzusatz is NULL) or
               (SLAVE.SlaveStatus = 'In Abreitand
               SLAVE.Dzusatz = 'Gesperrtand
               SLAVE.Sollende < Current_Date))
           and MASTER.FATW = 'Aktive'
       ) as Kernselect
 where (( (Kernselect.AltesSystem like 'Start%or Kernselect.AltesSystem like 'Vorgang%')
         and Kernselect.AltesSystem not like '%Abbruch%
         and Kernselect.Storno is null
        )
       or
        (Kernselect.referenznr = 'ABT_25')
       )
Wie man genau die Kriterien nach innen oder außen legt, muss anhand des Ausführungsplans oder Try/Error bestimmt werden. Ach und nochmal die Frage: Sind es wirklich alles Outer Joins oder vielleicht doch feste Joins? Ändert sich die Ergebnismenge, wenn Du feste Joins draus machst?
Gruß, Jo

Geändert von jobo (23. Jun 2016 um 12:59 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:45 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz