Neuigkeiten:

Wenn ihr euch für eine gute Antwort bedanken möchtet, im entsprechenden Posting einfach den Knopf "sag Danke" drücken!

Mobiles Hauptmenü

Grundsatz Frage zu Abfragen

Begonnen von Bernie110, September 29, 2014, 15:01:12

⏪ vorheriges - nächstes ⏩

Bernie110

Hallo Franz,

in Ordnung. Nun habe ich die BeispielDB nochmals etwas angepasst.

Bitte fragt, wenn es immer noch zu unverständlich ist.

Ich möchte doch nur Sendungen von A nach B und dann nach C schicken :-)

Lg Bernie

Bernie110

Hallo Zusammen,

das würde meine Frage beantworten.

https://www.youtube.com/watch?v=AnbjK3nhry0

Was hält ihr davon ?
Lg Bernie

Bernie110

Ich hab das nun mal aus probiert und 4 Abfragen so wie im Video beschrieben eingebunden..

ich sag nur Boa ist das schnell..

Jetzt bleibt nunr noch die Frage zu klären.. Ist das zeilführend oder nicht ?

Lg Bernie

Ps. bin schon mal gespannt auf eure Antworten

ebs17

Das was im Video beschrieben ist, ist hier (klick mich) ebenfalls kurz beschrieben.

Dazu als Statement: Ob eine Abfrage eine weitere Abfrage aufruft und diese wieder eine weitere oder ob man die SQL-Anweisungen dieser Abfragen zu einer zusammenfasst und diese ausführt, ist hinsichtlich Performance erst einmal egal.
Eine Abfrage enthält keine Daten, sondern nur die Definition, wie Daten aus Tabellen/Abfragen zu holen und zu verarbeiten sind. Im Ergebnis muss also die ganze Litanei abgearbeitet werden, so oder so.

Allerdings: In der zusammengefassten SQL-Anweisung gewinnt man eher einen Überblick.

- So kann man z.B. Felder (oder ganze Tabellen) in Teilabfragen beseitigen, die für die insgesamte Berechnung nicht benötigt werden => ein kleineres Recordset wird schneller zu verarbeiten sein.

- Im gleichen Sinne erkennt man unnötige Operationen in den Teilabfragen wie z.B. Sortierungen => Aufwand, aber keine Wirkung nach außen.

- Eine Abfrage wird vor Ausführung optimiert und daraus ein Ablaufplan erstellt, der nachfolgend verwendet wird. Die Optimierung kann aber nur von Vorhandenem ausgehen und dauert in Jet nicht sehr lange, ist also nicht das "Optimalste", sondern nur "nicht ganz schlecht".
Mit eigenem Abfragedesign, das man nun nur in der Gesamtansicht erkennt, kann man dem Optimierer helfen, einen guten und somit performanten Ablaufplan zu erstellen.

Zitat4 Abfragen so wie im Video beschrieben eingebunden..
Dann zeige doch mal die resultierende SQL-Anweisung.
Mit freundlichem Glück Auf!

Eberhard

Bernie110

Hallo Ebs,

das heisst also es hat keine wirkliche Auswirkung auf die Performance ?

Hier mal der zusammengefasste SQL String :

SELECT qyr_DISPO_TA_UFO_B2.LA_ID, X_A_qyr_LA_STATUS_B.STATUS_LA, qyr_DISPO_TA_UFO_B2.STATUS_TA, qyr_DISPO_TA_UFO_B2.NL, qyr_DISPO_TA_UFO_B2.TA_ID, qyr_DISPO_TA_UFO_B2.DT_NR, qyr_DISPO_TA_UFO_B2.DISPO_ART, qyr_DISPO_TA_UFO_B2.SNDG_ART, qyr_DISPO_TA_UFO_B2.Ladedatum, qyr_DISPO_TA_UFO_B2.Ladezeit, qyr_DISPO_TA_UFO_B2.Entladedatum, qyr_DISPO_TA_UFO_B2.Entladezeit, qyr_DISPO_TA_UFO_B2.TOUR_ID, qyr_DISPO_TA_UFO_B2.ABS_FirmenName1, qyr_DISPO_TA_UFO_B2.ABS_Strasse2, qyr_DISPO_TA_UFO_B2.ABS_Land, qyr_DISPO_TA_UFO_B2.ABS_Plz, qyr_DISPO_TA_UFO_B2.ABS_Ort, qyr_DISPO_TA_UFO_B2.ABS_Ort_Lang, qyr_DISPO_TA_UFO_B2.EMPF_FirmenName1, qyr_DISPO_TA_UFO_B2.EMPF_Land, qyr_DISPO_TA_UFO_B2.EMPF_Plz, qyr_DISPO_TA_UFO_B2.EMPF_Ort, qyr_DISPO_TA_UFO_B2.EMPF_Ort_Lang, qyr_DISPO_TA_UFO_B2.Colli, qyr_DISPO_TA_UFO_B2.KG, qyr_DISPO_TA_UFO_B2.LM, qyr_DISPO_TA_UFO_B2.Qbm, qyr_DISPO_TA_UFO_B2.LTW_ID, qyr_DISPO_TA_UFO_B2.LTW, qyr_DISPO_TA_UFO_B2.DISPO_Markierung, qyr_DISPO_TA_UFO_B2.AuftragsNr, qyr_DISPO_TA_UFO_B2.AuftragsNr, qyr_DISPO_TA_UFO_B2.[NOT].FirmenName1, qyr_DISPO_TA_UFO_B2.AG.FirmenName1, qyr_DISPO_TA_UFO_B2.ABS.FirmenName1, qyr_DISPO_TA_UFO_B2.EMPF.FirmenName1, qyr_DISPO_TA_UFO_B2.PA, qyr_DISPO_TA_UFO_B2.KA, qyr_DISPO_TA_UFO_B2.RO, qyr_DISPO_TA_UFO_B2.LS_NR
FROM qyr_DISPO_TA_UFO_B2 INNER JOIN [SELECT qyr_DISPO_TA_UFO_B1.NL,qyr_DISPO_TA_UFO_B1.STATUS_TA,qyr_DISPO_TA_UFO_B1.LA_ID,qyr_DISPO_TA_UFO_B1.TA_ID,qyr_DISPO_TA_UFO_B1.DT_NR,qyr_DISPO_TA_UFO_B1.DISPO_ART,qyr_DISPO_TA_UFO_B1.SNDG_ART,qyr_DISPO_TA_UFO_B1.Ladedatum,qyr_DISPO_TA_UFO_B1.Ladezeit,qyr_DISPO_TA_UFO_B1.Entladedatum,qyr_DISPO_TA_UFO_B1.Entladezeit,qyr_DISPO_TA_UFO_B1.TOUR_ID,qyr_DISPO_TA_UFO_B1.ABS_FirmenName1,qyr_DISPO_TA_UFO_B1.ABS_Strasse2,qyr_DISPO_TA_UFO_B1.ABS_Land,qyr_DISPO_TA_UFO_B1.ABS_Plz,qyr_DISPO_TA_UFO_B1.ABS_Ort,qyr_DISPO_TA_UFO_B1.ABS_Ort_Lang,qyr_DISPO_TA_UFO_B1.EMPF_FirmenName1,qyr_DISPO_TA_UFO_B1.EMPF_Land,qyr_DISPO_TA_UFO_B1.EMPF_Plz,qyr_DISPO_TA_UFO_B1.EMPF_Ort,qyr_DISPO_TA_UFO_B1.EMPF_Ort_Lang,qyr_DISPO_TA_UFO_B1.Colli,qyr_DISPO_TA_UFO_B1.KG,qyr_DISPO_TA_UFO_B1.LM,qyr_DISPO_TA_UFO_B1.Qbm,qyr_DISPO_TA_UFO_B1.LTW_ID,qyr_DISPO_TA_UFO_B1.LTW,qyr_DISPO_TA_UFO_B1.DISPO_Markierung,Y_A_qyr_DT_mit_Adressen.AuftragsNr,Y_A_qyr_DT_mit_Adressen.[NOT].FirmenName1,Y_A_qyr_DT_mit_Adressen.AG.FirmenName1,Y_A_qyr_DT_mit_Adressen.ABS.FirmenName1,Y_A_qyr_DT_mit_Adressen.EMPF.FirmenName1,qyr_DISPO_TA_UFO_B1.PA,qyr_DISPO_TA_UFO_B1.KA,qyr_DISPO_TA_UFO_B1.RO,qyr_DISPO_TA_UFO_B1.LS_NR
FROM qyr_DISPO_TA_UFO_B1 INNER JOIN (SELECT qyr_DISPO_TA_UFO_B.TA_ID,qyr_DISPO_TA_UFO_B.LA_ID,qyr_DISPO_TA_UFO_B.STATUS_TA,qyr_DISPO_TA_UFO_B.NL,qyr_DISPO_TA_UFO_B.DT_NR,qyr_DISPO_TA_UFO_B.DISPO_ART,qyr_DISPO_TA_UFO_B.SNDG_ART,qyr_DISPO_TA_UFO_B.Ladedatum,qyr_DISPO_TA_UFO_B.Ladezeit,qyr_DISPO_TA_UFO_B.Entladedatum,qyr_DISPO_TA_UFO_B.Entladezeit,qyr_DISPO_TA_UFO_B.TOUR_ID,qyr_DISPO_TA_UFO_B.ABS_FirmenName1,qyr_DISPO_TA_UFO_B.ABS_Strasse2,qyr_DISPO_TA_UFO_B.ABS_Land,qyr_DISPO_TA_UFO_B.ABS_Plz,qyr_DISPO_TA_UFO_B.ABS_Ort,qyr_DISPO_TA_UFO_B.ABS_Ort_Lang,qyr_DISPO_TA_UFO_B.EMPF_FirmenName1,qyr_DISPO_TA_UFO_B.EMPF_Land,qyr_DISPO_TA_UFO_B.EMPF_Plz,qyr_DISPO_TA_UFO_B.EMPF_Ort,qyr_DISPO_TA_UFO_B.EMPF_Ort_Lang,qyr_DISPO_TA_UFO_B.LTW_ID,qyr_DISPO_TA_UFO_B.LTW,qyr_DISPO_TA_UFO_B.DISPO_Markierung,Z_qyr_TA_PACKSTÜCKE_C.Colli,Z_qyr_TA_PACKSTÜCKE_C.LM,Z_qyr_TA_PACKSTÜCKE_C.Qbm,Z_qyr_TA_PACKSTÜCKE_C.KG,Z_qyr_TA_PACKSTÜCKE_C.PA,Z_qyr_TA_PACKSTÜCKE_C.KA,Z_qyr_TA_PACKSTÜCKE_C.RO,qyr_DISPO_TA_UFO_B.LS_NR
FROM qyr_DISPO_TA_UFO_B LEFT JOIN (SELECT qyr_DISPO_TA_UFO_A.TA_ID,qyr_DISPO_TA_UFO_A.STATUS_TA,qyr_DISPO_TA_UFO_A.LA_ID,qyr_DISPO_TA_UFO_A.NL,qyr_DISPO_TA_UFO_A.DT_NR,qyr_DISPO_TA_UFO_A.DISPO_ART,qyr_DISPO_TA_UFO_A.SNDG_ART,qyr_DISPO_TA_UFO_A.Ladedatum,qyr_DISPO_TA_UFO_A.Ladezeit,qyr_DISPO_TA_UFO_A.Entladedatum,qyr_DISPO_TA_UFO_A.Entladezeit,qyr_DISPO_TA_UFO_A.TOUR_ID,qyr_DISPO_TA_UFO_A.ABS_FirmenName1,qyr_DISPO_TA_UFO_A.ABS_Strasse2,qyr_DISPO_TA_UFO_A.ABS_Land,qyr_DISPO_TA_UFO_A.ABS_Plz,qyr_DISPO_TA_UFO_A.ABS_Ort,qyr_DISPO_TA_UFO_A.ABS_Ort_Lang,qyr_DISPO_TA_UFO_A.EMPF_FirmenName1,qyr_DISPO_TA_UFO_A.EMPF_Land,qyr_DISPO_TA_UFO_A.EMPF_Plz,qyr_DISPO_TA_UFO_A.EMPF_Ort,qyr_DISPO_TA_UFO_A.EMPF_Ort_Lang,qyr_DISPO_TA_UFO_A.LTW_ID,qyr_DISPO_TA_UFO_A.LTW,qyr_DISPO_TA_UFO_A.DISPO_Markierung,V_LA_MA_TABELLE.LS_NR
FROM qyr_DISPO_TA_UFO_A LEFT JOIN (SELECT TA_TABELLE.TA_ID,TA_TABELLE.STATUS_TA,TA_TABELLE.LA_ID,TA_TABELLE.NL,TA_TABELLE.DT_NR,TA_TABELLE.DISPO_ART,TA_TABELLE.SNDG_ART,TA_TABELLE.ABS_ID,TA_TABELLE.EMPF_ID,TA_TABELLE.Ladedatum,TA_TABELLE.Ladezeit,TA_TABELLE.Entladedatum,TA_TABELLE.Entladezeit,TA_TABELLE.TOUR_ID,KD_TABELLE.FirmenName1 AS ABS_FirmenName1,KD_TABELLE.Strasse2 AS ABS_Strasse2,KD_TABELLE.Land AS ABS_Land,KD_TABELLE.Plz AS ABS_Plz,KD_TABELLE.Ort AS ABS_Ort, [ABS_LAND] & "-" & [ABS_Plz] & " " & [ABS_Ort] AS ABS_Ort_Lang,KD_TABELLE_1.FirmenName1 AS EMPF_FirmenName1,KD_TABELLE_1.Land AS EMPF_Land,KD_TABELLE_1.Plz AS EMPF_Plz,KD_TABELLE_1.Ort AS EMPF_Ort, [EMPF_LAND] & "-" & [EMPF_Plz] & " " & [EMPF_Ort] AS EMPF_Ort_Lang,TA_TABELLE.LTW_ID,TA_TABELLE.LTW,TA_TABELLE.DISPO_Markierung
FROM KD_TABELLE INNER JOIN (TA_TABELLE INNER JOIN KD_TABELLE AS KD_TABELLE_1 ON TA_TABELLE.EMPF_ID = KD_TABELLE_1.KD_ID) ON KD_TABELLE.KD_ID = TA_TABELLE.ABS_ID) AS V_LA_MA_TABELLE ON qyr_DISPO_TA_UFO_A.LA_ID = V_LA_MA_TABELLE.LA_ID) AS Z_qyr_TA_PACKSTÜCKE_C ON qyr_DISPO_TA_UFO_B.LA_ID = Z_qyr_TA_PACKSTÜCKE_C.LA_ID) AS Y_A_qyr_DT_mit_Adressen ON qyr_DISPO_TA_UFO_B1.DT_NR = Y_A_qyr_DT_mit_Adressen.DT_NR]. AS X_A_qyr_LA_STATUS_B ON qyr_DISPO_TA_UFO_B2.LA_ID = X_A_qyr_LA_STATUS_B.LA_ID;


Ich hoffe ich hab das auch richtige gemacht. Funktioniert jedenfalls.

Im Ufo lasse ich folgende Felder anzeigen.

TA_ID
DISPO_ART
STATUS_TA
LA_STATUS
Ladezeit
ABS_Ort_Lang
EMPF_Ort_Lang
CLL
Ladedatum
KG
LM
NL
SNDG_ART
QBM
KA
RO
DISPO_Markierung
LTW_ID
LTW
Entladedatum
Entladezeit
DT_NR
LA_ID
TOUR_ID
NOT
AuftragsNr
ABS_Land
ABS_Plz
ABS_Ort
EMPF_Land
EMPF_Plz
EMPF_Land
EMPF_Ort
FHZ_BEZ
FirmenName1


Die DB wird momentan in Access 2000 entwickelt und soll aber später in eine Access 2013 DB konvertiert werden.
Im Anschluss werden dann die Tabellen in einen SQL Server eingebunden.
Das wäre mal der Plan. Stellt sich die Frage wie hoch die Performance sein wird, wenn ca 50 User in 6 Niederlassungen damit arbeiten.
Ausgehen muss man von ca 200.000 DS je Jahr oder mehr.

Eine Frage habe ich jedoch noch.
Da Abfragen bei komplexen Berechnungen ziemlichen Arbeitsspeicher benötigen, wäre es aus meiner Logik heraus doch besser das Abfrage Ergebnis in eine neue Tabelle zuspeichern oder ?
Sind die Daten in einer neuen Tabelle bereits berechnet, muss nicht jeder weitere User der die Daten benötigt, diese nicht erneut berechnen lassen usw.
Was meine ich :

Die og Abfrage berechnet eben zb Felder wie QBM,LM,KG,Colli,PA,KA,RO immer wieder,
Man könnte sich 2 - 3 Abfragen sparen wenn man es einmal berechent und dann das Ergebnis in eine neue Tabelle speichert.

Ich nehme mal an das diese vorgehnsweise falsch ist oder ?

Lg Bernie



Wurliwurm

Zitat von: Bernie110 am Oktober 05, 2014, 11:43:02
Stellt sich die Frage wie hoch die Performance sein wird, wenn ca 50 User in 6 Niederlassungen damit arbeiten.
Ausgehen muss man von ca 200.000 DS je Jahr oder mehr.

Eine Frage habe ich jedoch noch.
Da Abfragen bei komplexen Berechnungen ziemlichen Arbeitsspeicher benötigen, wäre es aus meiner Logik heraus doch besser das Abfrage Ergebnis in eine neue Tabelle zuspeichern oder ?
Sind die Daten in einer neuen Tabelle bereits berechnet, muss nicht jeder weitere User der die Daten benötigt, diese nicht erneut berechnen lassen usw

Die Abfrage sieht ziemlich doll aus. Ob sie so gut geschrieben ist oder vereinfacht werden kann, habe ich nicht hinterfragt.

Die Berechnung der Unterabfragen braucht natürlich Hauptspeicher und auch Rechenzeit. Bei Benutzung einer Access-Datei als Backend über das Netz müssen dann außerdem vorher weitgehend alle Daten über das Netz transferiert werden und auf dem Client-PC verarbeitet werden. Das würde bei einer mittelgroßen Datenbank selbst bei schnellem Netzwerk unzumutbar für die Performance sein.

Zu Deiner Frage: Ja, es kann sinnvoll sein, Abfrageergebnisse materialisiert vorzuhalten. Datenbanksysteme haben dies als Feature. Es läuft im Idealfall auch transparent, d.h. das Datenbanksystem entscheidet im Hintergrund, ob es eine materialisierte Abfrage verwendet oder aus den Basistabellen neu errechnet.

Auf dem SQL-Server kann man anzeigen lassen, wie eine Abfrage abgearbeitet wird (Explain-Plan). Die Performance von Abfragen und wie man sie verbessert, ist eine durchaus nicht triviale Thematik, für die man jahrelang sich spezialisieren muß, um sie wirklich voll drauf zu haben.

Das ist dann aber kein Access-Thema mehr. Ich würde aus praktischen Gründen die Abfragen nur auf dem SQL-Server erstellen und optimieren und gegebenfalls Experten hinzuziehen. Gegenenfalls muß auch etwas am Datenmodell gemacht werden (teilweiser Verzicht auf Normalformen in den Tabellen). Im Access hingegen würde ich als Datenquelle für die Entwicklung der Formulare vorübergehend eine "Mock"-Tabelle erstellen, welche die Spalten der Abfrage hat.

ebs17

#21
Zitates hat keine wirkliche Auswirkung auf die Performance ?
Nun, es könnte schon sein, dass der Abfrageoptimierer wegen der Verknüpfungen teilweise zu einem anderen Ablaufplan kommt. Performance heißt ja verbrauchte Zeit. Wenn Du zwei funktionierende Varianten hast, kannst Du jene einfach messen.

ZitatIm Anschluss werden dann die Tabellen in einen SQL Server eingebunden.
Das als pure Maßnahme ist schlicht Unsinn, weil im Ergebnis Deine Abfragen dann langsamer laufen werden als bei einem Access-Backend. Erklärungen dazu entnimmst Du besser im Zusammenhang einem Buch wie ACCESS und SQL SERVER.
Wenn Du doppelte Arbeit vermeiden willst, erstellst Du Deine Tabellen und die wesentlichen Abfragen gleich im SQL Server und Access ist dann für das Frontend zuständig.
Dann wird die Performance bestmöglich sein, weil der SQL Server (richtig angesprochen) nur noch Berechnungsergebnisse liefert und nicht zusätzlich umfangreiche Daten für notwendige Berechnungen.

In jedem Fall: Neben der Tabellenplanung (Datenmodellierung) sollte man auch gleich einen Blick auf die Indexplanung werfen, da gibt es laufend wiederholte Fehler, auch in Deiner DB.
Performance in Abfragen von Michael Zimmermann

Zur SQL-Anweisung: Die ist nun etwas ganz anderes als die Zusammensetzung der Abfragen in der ersten DB.
So richtig analysieren kann und braucht man dieses "flächenhafte Gebilde" aber nicht. Mein Formatierer steigt da aus, so dass Logik (Tiefenschachtelung) nicht erkennbar ist. Die enthaltenen Abfragen müsste man zusätzlich ob des Inhalts nachschlagen.
Beim Überfliegen der Anweisung sieht man eigentlich nur JOIN's, und zwar allerhand. Da kann man, passende Schlüssel vorausgesetzt, nicht viel verkehrt machen als dass man zuviel macht.

ZitatIm Ufo lasse ich folgende Felder anzeigen.
Ich bin kein Freund von Breitwandmonitor-Formularen und entsprechenden Abfragen. Gerade Access bietet doch einfache Möglichkeiten, Formulare zu erstellen und diese zu verschachteln, so dass eine Datenbasis der Einzelformulare übersichtlich und weniger komplex sein muss.
Mit freundlichem Glück Auf!

Eberhard

Bernie110

Og, danke , das hilft mir schon mal weiter
Lg Bernie