AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Access SQL Query optimieren?
Thema durchsuchen
Ansicht
Themen-Optionen

Access SQL Query optimieren?

Ein Thema von HCB · begonnen am 14. Jan 2024 · letzter Beitrag vom 17. Jan 2024
Antwort Antwort
Seite 1 von 2  1 2      
HCB

Registriert seit: 12. Feb 2020
136 Beiträge
 
Delphi 12 Athens
 
#1

Access SQL Query optimieren?

  Alt 14. Jan 2024, 11:40
Datenbank: Access mdb • Version: 2003 • Zugriff über: FireDac
Hallo SQL Experten,
ich brauche mal wieder euere Hilfe in Sachen SQL Abfrage in einer mdb Access Datenbank. Für den ersten Aufruf meiner Abfrage dauert es 16 sek. bis das Ergebnis korrekt angezeigt wird.
Bei einer anschließenden nochmaligen Abfrage dauert es nur die Hälfte der Zeit. Die mdb Datei liegt auf einem Win 10 Rechner im lokalen Netzwerk. Der App PC greift darauf zu.

Meine Frage1: Warum dauert es bei der Erstabfrage so lange und auf welchem Rechner wird die Abfrage gecached (Win10 Netzwerkrechner oder lokaler PC) weil es dann schneller geht?
Frage2: Kann man durch Optimierung der SQL-Query ein schnelleres Resultat erreichen?

Hier mein Query:
Delphi-Quellcode:
SELECT ABFDocAuftragNr, ABFDocDatum,ABFDocKundeKurzbez,
IIF(Count(ABFDocAuftragID)>1,Max(ABFPosMenge)-Min(ABFPosMenge),Max(ABFPosMenge)) as offen
FROM (ABFDok INNER JOIN ABFPos
ON ABFPos.ABFPosAuftragID = ABFDok.ABFDocAuftragID)
INNER JOIN sArtikel
      ON ABFPos.ABFPosArtNr=sArtikel.ArtNr
where ABFDocOptFertig = false and ABFDocVisType= 1 and ABFPosEPreis >0 and ABFPosType in(0,7) and ABFPosNr <>'and ABFPosArtNr = :ArtNr
GROUP BY ABFDocAuftragNr,ABFDocDatum,ABFDocKundeKurzbez,ABFdocVisType
order by ABFDocAuftragNr;
Wenn einer mir helfen könnte wäre ich sehr sehr dankbar.

LG Harry
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.418 Beiträge
 
Delphi 7 Professional
 
#2

AW: Access SQL Query optimieren?

  Alt 14. Jan 2024, 12:03
Das kenne ich auch von FireBird.

Ab der zweiten Abfrage wird's schneller, weil ein Teil der Datenbankdatei bereits gelesen wurde und damit im Cache der Festplatte liegt.

Wenn Du lange wartest und in der Zeit andere Programme die Festplatte extensiv nutzen, wird die Abfrage wieder einmal langsamer werden und beim zweiten Mal wieder schneller.

Das Problem liegt eher an Windows und der Hardware als an der Datenbank.

SQL-Code:
SELECT
  ABFDocAuftragNr,
  ABFDocDatum,
  ABFDocKundeKurzbez,
  IIF(Count(ABFDocAuftragID) > 1,Max(ABFPosMenge) - Min(ABFPosMenge), Max(ABFPosMenge)) as offen
FROM
(
  ABFDok
  INNER JOIN ABFPos ON ABFPos.ABFPosAuftragID = ABFDok.ABFDocAuftragID
)
INNER JOIN sArtikel ON ABFPos.ABFPosArtNr = sArtikel.ArtNr
where ABFDocOptFertig = false
  and ABFDocVisType = 1
  and ABFPosEPreis > 0
  and ABFPosType in(0,7)
  and ABFPosNr <>'
  and ABFPosArtNr = :ArtNr
GROUP BY
  ABFDocAuftragNr,
  ABFDocDatum,
  ABFDocKundeKurzbez,
  ABFdocVisType
order by
  ABFDocAuftragNr;
Zu welcher Tabelle gehören diese Einschränkungen?
SQL-Code:
where ABFDocOptFertig = false
  and ABFDocVisType = 1
  and ABFPosEPreis > 0
  and ABFPosType in(0,7)
  and ABFPosNr <> '
  and ABFPosArtNr = :ArtNr
Eventuell solltest Du die entsprechende(n) Tabelle(n) erst per Wherebedingung einschränken und dann per Join die anderen Tabellen dazunehmen.

Wie sehen die Tabellendefinitionen aus? Wie sehen die Indexdefinitionen aus?

Geändert von Delphi.Narium (14. Jan 2024 um 12:13 Uhr) Grund: Schreibfehler
  Mit Zitat antworten Zitat
HCB

Registriert seit: 12. Feb 2020
136 Beiträge
 
Delphi 12 Athens
 
#3

AW: Access SQL Query optimieren?

  Alt 14. Jan 2024, 12:20
Danke für die schnelle Antwort.

Delphi-Quellcode:
 where ABFDocOptFertig = false
  and ABFDocVisType = 1 //zur Tabelle ABFDoc

  and ABFPosEPreis > 0
  and ABFPosType in(0,7)
  and ABFPosNr <> '
  and ABFPosArtNr = :ArtNr // zur Tabelle ABFPos
Mastersource = sArtikel
MasterFields = sArtikel.ArtNr
IndexesActive = true

Frage: Was kann ich in Windows einstellen (Programme im Hintergrund ist aktiv) damit ich das verbessern kann, bzw. reicht die Hardware nicht aus? (16 gB RAM, SSD Festplatte).

LG Harry
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.418 Beiträge
 
Delphi 7 Professional
 
#4

AW: Access SQL Query optimieren?

  Alt 14. Jan 2024, 13:27
Über welche Datenmengen reden wir denn überhaupt? 16 Sekunden bei 100 Sätzen ist sicherlich lang, 16 Sekunden bei 100.000.000.000 eher nicht Wie groß ist die Datenbankdatei?

Nur hingedaddelt und ungetestet und zusätzlich keine Ahnung, ob Access mit 'ner Syntax in der Form zurechtkommt. Aber eventuell wird verständlich, worauf ich hinausmöchte. Und ob das dann auch noch schneller wird kommt auf Versuch und Irrtum an. Grundsätzlich versuche ich bei großen Datenmengen diese möglichst früh maximal einzuschränken, bevor per Join mehrere Tabellen zusammengefügt werden. (Und Ja, die Lesbarkeit von SQL-Statements kann darunter leiden. Kürzere Laufzeiten gehen leider zuweilen (massiv) zu Lasten der Lesbarkeit der SQLs.)
SQL-Code:
select
  ABFDocAuftragNr,
  ABFDocDatum,
  ABFDocKundeKurzbez,
  IIF(Count(ABFDocAuftragID) > 1,Max(ABFPosMenge) - Min(ABFPosMenge), Max(ABFPosMenge)) as offen
from
(
  (
    select ABFDocAuftragNr, ABFDocDatum, ABFDocKundeKurzbez, ABFDocAuftragID
    from ABFDoc
    where ABFDocOptFertig = false
      and ABFDocVisType = 1
  ) a
  inner join
  (
    select ABFPosArtNr, ABFPosMenge
    from ABFPos
    where ABFPosEPreis > 0
      and ABFPosType in(0,7)
      and ABFPosNr <> '
      and ABFPosArtNr = :ArtNr
  ) b on b.ABFPosAuftragID = a.ABFDocAuftragID
) c
group by
  ABFDocAuftragNr,
  ABFDocDatum,
  ABFDocKundeKurzbez,
  ABFdocVisType
order by
  ABFDocAuftragNr;
Den inner join sArtikel on c.ABFPosArtNr = sArtikel.ArtNr hab' ich rausgenommen, da für mich nicht erkennbar ist, ob und ggfls. wofür ein Join auf diese Tabelle erforderlich sein sollte. Im Ergebnis scheinen keine Daten aus sArtikel enthalten zu sein, für die Wherebedingungen scheint sie auch nicht benötigt zu werden. Dann ist sie in diesem SQL eigentlich auch überflüssig und frist nur Speicher und Laufzeit.

Bevor Du anfängst an Windows und / oder Hardware zu schrauben, schau bitte erstmal, ob Du datenbankseitig eine Beschleunigung hinbekommst. Datenträger haben nunmal Zugriffzeiten > 0, von daher werden Datenbankabfragen auch immer mit Laufzeiten > 0 ausgeführt. Und wenn es dann auch noch über ein Netzwerk geht, muss der APP PC (bei Access) halt die ganze Datenbankdatei "mal eben über die Leitung ziehen", um dann die Auswertung vornehmen zu können. Access ist halt keine Datenbank, bei der der Client sagen kann. "Lieber Datenbankserver gib mir mal die Daten entsprechend der Dir hiermit übergebenen Abfrage."

Letztlich sind wir dann aber wieder bei dem Thema: Access Datenbank langsam, vermutlich reden wir hier über das gleiche WW-System?
  Mit Zitat antworten Zitat
HCB

Registriert seit: 12. Feb 2020
136 Beiträge
 
Delphi 12 Athens
 
#5

AW: Access SQL Query optimieren?

  Alt 14. Jan 2024, 15:02
Es handelt sich um 180000 Datensätze in einer Master-Detail Beziehung.
Master = sArtikel (gibt ArtNr vor) > Detail = Abfrage aus ABFDok und ABFPos.

Ja, ich knappere immer noch an der Performance herum.
Bei jedem DataChange wird die Query aufgerufen. Ist nicht optimal, deshalb muss ich weitere Lösungen finden.

Danke für die Zeit die du dir nimmst.

LG Harry
P.S. Syntaxfehler in FROM-Klausel bei deinem Vorschlag. Mal sehen was ich daraus machen kann.
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.418 Beiträge
 
Delphi 7 Professional
 
#6

AW: Access SQL Query optimieren?

  Alt 14. Jan 2024, 15:20
Teil Dir das SQL von innen nach außen auf:

Funktioniert das?
SQL-Code:
    select ABFDocAuftragNr, ABFDocDatum, ABFDocKundeKurzbez, ABFDocAuftragID
    from ABFDoc
    where ABFDocOptFertig = false
      and ABFDocVisType = 1
Funktioniert das?
SQL-Code:
    select ABFPosArtNr, ABFPosMenge
    from ABFPos
    where ABFPosEPreis > 0
      and ABFPosType in(0,7)
      and ABFPosNr <> '
      and ABFPosArtNr = :ArtNr
Funktioniert das?
SQL-Code:
select
*
from
(
  (
    select ABFDocAuftragNr, ABFDocDatum, ABFDocKundeKurzbez, ABFDocAuftragID
    from ABFDoc
    where ABFDocOptFertig = false
      and ABFDocVisType = 1
  ) a
  inner join
  (
    select ABFPosArtNr, ABFPosMenge
    from ABFPos
    where ABFPosEPreis > 0
      and ABFPosType in(0,7)
      and ABFPosNr <> '
      and ABFPosArtNr = :ArtNr
  ) b on b.ABFPosAuftragID = a.ABFDocAuftragID
)
Es kann sein, dass Access mit der Art der Schachtelung der Selects nicht zurechtkommt.

Hab' grade mal mit FireBird ein ähnliches Konstrukt hingedaddelt. dort muss vor dem group by das c weg.

Geht es so?
SQL-Code:
select
  ABFDocAuftragNr,
  ABFDocDatum,
  ABFDocKundeKurzbez,
  IIF(Count(ABFDocAuftragID) > 1,Max(ABFPosMenge) - Min(ABFPosMenge), Max(ABFPosMenge)) as offen
from
(
  (
    select ABFDocAuftragNr, ABFDocDatum, ABFDocKundeKurzbez, ABFDocAuftragID
    from ABFDoc
    where ABFDocOptFertig = false
      and ABFDocVisType = 1
  ) a
  inner join
  (
    select ABFPosArtNr, ABFPosMenge
    from ABFPos
    where ABFPosEPreis > 0
      and ABFPosType in(0,7)
      and ABFPosNr <> '
      and ABFPosArtNr = :ArtNr
  ) b on b.ABFPosAuftragID = a.ABFDocAuftragID
)
group by
  ABFDocAuftragNr,
  ABFDocDatum,
  ABFDocKundeKurzbez,
  ABFdocVisType
order by
  ABFDocAuftragNr;
  Mit Zitat antworten Zitat
HCB

Registriert seit: 12. Feb 2020
136 Beiträge
 
Delphi 12 Athens
 
#7

AW: Access SQL Query optimieren?

  Alt 14. Jan 2024, 15:42
SQL Code 1 läuft,
SQL Code 2 läuft,
SQL Code 3: 2 Parameter wurden erwartet, aber es wurden zu wenig Parameter übergeben bzw. Mit '*' ausgewählte Felder können nicht gruppiert werden
SQL Code 4: 2 Parameter wurden erwartet, aber es wurden zu wenig Parameter übergeben
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.418 Beiträge
 
Delphi 7 Professional
 
#8

AW: Access SQL Query optimieren?

  Alt 14. Jan 2024, 16:05
Das liegt eventuell hierdran:  and ABFPosArtNr = :ArtNr

Wenn Du das als reines SQL ausführen lässt, musst Du statt :ArtNr einen konkreten Wert eingeben.

Wobei:

Access neigt dazu bei Schreibfehlern in Spaltennamen, teils auch bei Syntaxfehlern, ... auch schonmal von fehlenden Parameterangaben zu sprechen.

Da es im SQL nur einen Parameter gibt, Access aber zwei Parameter bemängelt, liegt es entweder an Schreib- und/oder Syntaxfehlern oder Access kommt mit dieser Art von SQL-Verschachtelung nicht zurecht.

Ohne Access und die entsprechende Datenbank ist das recht schwierig (eigentlich garnicht) nachzuvollziehen.
  Mit Zitat antworten Zitat
HCB

Registriert seit: 12. Feb 2020
136 Beiträge
 
Delphi 12 Athens
 
#9

AW: Access SQL Query optimieren?

  Alt 14. Jan 2024, 16:42
Ja ich weiß: and ABFPosArtNr = :ArtNr, da hb ich schon die Artikelnummer zum Testen eingegebn: and ABFPosArtNr = '10621008'
Artikelnummer ist ein Textfeld.
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.270 Beiträge
 
Delphi 10.4 Sydney
 
#10

AW: Access SQL Query optimieren?

  Alt 15. Jan 2024, 06:03
Hallo,
wie sieht es mit fehlenden Indices aus?
Heiko
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 05:00 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