Discussion:
DB-Versionen von Access
(zu alt für eine Antwort)
Thomas Raasch
2008-12-08 13:20:54 UTC
Permalink
Hallo NG,

ich habe eine vermutlich veraltete Frage...
wir bauen Access-Progrämmchen für die Auftragsbearbeitung. Die Programme
sind bei manchen Kunden nun seit einigen Jahren im Einsatz. Das Format der
Access-Anwendung (FE) ist AccXP. Die reine Datenbank (BE) liegt ebenfalls
als AccXP vor. Die DB liegt idR. in einer Freigabe auf nem Windows-Server.
Das Netz ist zumeist nen 100MBit LAN.


Es häufen sich nun leider die Beschwerden, dass die Anwendung immer
langsamer und langsamer wird. Habe daraufhin getestet:
das Öffnen eines Formulars (Inhalt: Aufträge) dauert schonmal gerne 30s. Die
DB hat 150 MB und die angesprochene Tabelle hat ca. 60.000 Datensätze. Laut
System-Überwachungs-Tools holt sich Access bei Formularstart die komplette
Tabelle mit allen 60.000 Datensätzen, wertet danach lokal am Client den
FilterBy und OrderBy aus und zeigt das Ergebnis an.
Das Ordern und Filtern geht dabei in Sekundenschnelle - aber das Übertragen
der Tabelle durchs LAN dauert....


OK, das ist mit Access evtl. nicht anders machbar - dazu gibts ja dann den
SQL-Server. Gut... aber ich habe etwas rumprobiert und folgendes
festgestellt:
Wenn ich nur in dieser einen Tabelle (Aufträge) bei allen Text-Feldern die
Option "Unicode-Komprimierung" aktiviere und die DB komprimiere verliert sie
über 5 MB Dateigröße. Das Starten des Formulars sinkt herab von 29s auf 22s.
Schomal gut aber noch immer zu langsam.
Wenn ich aber die DB - also nur das BackEnd - im Access97-Format speichere
dann sinkt die DB-Größe um 40 MB! Der Start des Formulars sinkt hierbei von
29s auf 18s! Das ist doch schon viel besser...


Die Tabellen sind gut strukturiert und normalisiert. Als DS-Herkunft für das
Form hängt nur die Tabelle dran - keine komplexe Abfrage. Als Datentypen der
Tabellenfelder sind bereits immer die kleinst-möglichen gewählt.


Meine Frage nun:
Kann ich einfach das BackEnd (also nur die Datenbank) in Acc97 konvertieren
und weiterhin mit dem AccXP FrontEnd darauf arbeiten? Meine Tests sind
soweit positiv verlaufen.
Welche Überraschungen erwarten mich?
Welche Vorteile bringt das größere (und damit langsamere) AccXP-Format? Habe
was von Unicode gelesen... braucht man das? Ich möchte weder russische noch
chinesische Zeichen speichern :)

Falls eine Umstellung der Datenbank auf Acc97 nicht empfohlen ist: was hat
es mit der Unicode-Komprimierung bei AccXP auf sich? Warum ist diese per
default nicht aktiviert? Welche Nachteile gibt es hier?

Gibt es sonst noch "normale" Performance-Tipps? Als "normal" empfinde ich
vermutlich alles außer "nimm den SQL-Server" oder "steige um auf ungebundene
Formulare".


Vielen vielen Dank
und Grüße
Thomas
Jens Schilling
2008-12-08 13:38:38 UTC
Permalink
Hallo, Thomas
Post by Thomas Raasch
Gibt es sonst noch "normale" Performance-Tipps? Als "normal" empfinde
ich vermutlich alles außer "nimm den SQL-Server" oder "steige um auf
ungebundene Formulare".
Bevor Du irgend etwas anderes beginnst, geh' mal die Tipps und Links bei
Thomas durch :

http://www.team-moeller.de/access/tiptrick/performance.html
--
Gruss
Jens
______________________________
FAQ: http://www.donkarl.com
Thomas Raasch
2008-12-09 08:55:27 UTC
Permalink
Hi,
Post by Jens Schilling
Bevor Du irgend etwas anderes beginnst, geh' mal die Tipps und Links bei
http://www.team-moeller.de/access/tiptrick/performance.html
Hab ich durch - nicht ein Tipp brachte überhaupt eine Millisekunde :(
Das Problem ist nach wie vor, dass die komplette Datenmenge übers LAN
geschoben wird und _nur_ das dauert...

Schade
Grüße
Thomas
Lutz Uhlmann
2008-12-09 10:00:26 UTC
Permalink
Post by Thomas Raasch
Hab ich durch - nicht ein Tipp brachte überhaupt eine Millisekunde :(
Das Problem ist nach wie vor, dass die komplette Datenmenge übers LAN
geschoben wird und _nur_ das dauert...
Weiß nicht ob das bei euch praktikabel ist von der Nutzung der
Auftragstabelle her.
Aber eventuell bringt es etwas, die Auftäge-Tabelle aufzuteilen.
Bsw. könnte man alle Aufträge eines Jahres in jeweils eine Tabelle packen
"tabAuftrag2007".
Oder eine Tabelle für aktuell gültige Aufträge und eine Art Archiv-Tabelle
für alle alten Aufträge.

Ob das etwas bringt, könntest du ja schonmal testen, indem du in einer
Testumgebung mal 50.000 deiner 60.000 Datensätze rauslöschst.

Lutz
Thomas Raasch
2008-12-09 10:43:23 UTC
Permalink
Hi
Post by Lutz Uhlmann
Post by Thomas Raasch
Hab ich durch - nicht ein Tipp brachte überhaupt eine Millisekunde :(
Das Problem ist nach wie vor, dass die komplette Datenmenge übers LAN
geschoben wird und _nur_ das dauert...
Weiß nicht ob das bei euch praktikabel ist von der Nutzung der
Auftragstabelle her.
Aber eventuell bringt es etwas, die Auftäge-Tabelle aufzuteilen.
Bsw. könnte man alle Aufträge eines Jahres in jeweils eine Tabelle packen
"tabAuftrag2007".
Oder eine Tabelle für aktuell gültige Aufträge und eine Art Archiv-Tabelle
für alle alten Aufträge.
Ob das etwas bringt, könntest du ja schonmal testen, indem du in einer
Testumgebung mal 50.000 deiner 60.000 Datensätze rauslöschst.
Ja genau sowas hab ich schon gemacht... es geht wunderbar-superschnell wenn
ich 50.000 von 60.000 DS weglösche
Die Trennung in Tabellen mit Jahreszahlen wäre denkbar... oder würde
zumindest das Problem behebn. Nur wie soll dann eine ordentliche
Suchfunktion aussehen, die auch mal Daten in älteren Tabellen findet?!
Hmm ich werde drüber nachdenken.....


Aber die Datenmengen-Reduktion kann ich eben auch erreichen wenn ich
Unicode-Komprimierung anwende oder die DB in Acc97 konvertiere... Ein Paar
Hinweise und (negative) Fakten zu diesen Verfahren wären toll.


Grüße
Thomas
Lutz Uhlmann
2008-12-09 11:16:27 UTC
Permalink
Post by Thomas Raasch
Ja genau sowas hab ich schon gemacht... es geht wunderbar-superschnell
wenn ich 50.000 von 60.000 DS weglösche
Die Trennung in Tabellen mit Jahreszahlen wäre denkbar... oder würde
zumindest das Problem behebn. Nur wie soll dann eine ordentliche
Suchfunktion aussehen, die auch mal Daten in älteren Tabellen findet?!
Hmm ich werde drüber nachdenken.....
Wenn die Tabellen dieselbe Struktur haben, dann läuft die Suche analog über
jede Tabelle und kann beispielsweise mit einem Union zusammengefügt werden.

Bei einer Suche über älteren Daten (Archiv) sind längere Ladezeiten
sicherlich hinnehmbar, wenn dagegen die tägliche Arbeit schnell
bewerkstelligt werden kann.
Es kommt natürlich immer auf das spezielle Szenario an. Arbeiten deine
Kunden eher über aktuellen Aufträgen oder älteren.
Post by Thomas Raasch
Aber die Datenmengen-Reduktion kann ich eben auch erreichen wenn ich
Unicode-Komprimierung anwende oder die DB in Acc97 konvertiere... Ein Paar
Hinweise und (negative) Fakten zu diesen Verfahren wären toll.
Da können dir die anderen mehr sagen bzw. haben es bereits!

Lutz

P.S. Als Tipp evtl noch Josefs Skript von der AEK7.
http://www.donkarl.com/AEK/AEKDownloads/AEK7_PerfTuning.zip
Henry Habermacher
2008-12-09 12:03:04 UTC
Permalink
Hallo Lutz
Post by Lutz Uhlmann
Post by Thomas Raasch
Ja genau sowas hab ich schon gemacht... es geht wunderbar-superschnell
wenn ich 50.000 von 60.000 DS weglösche
Die Trennung in Tabellen mit Jahreszahlen wäre denkbar... oder würde
zumindest das Problem behebn. Nur wie soll dann eine ordentliche
Suchfunktion aussehen, die auch mal Daten in älteren Tabellen findet?!
Hmm ich werde drüber nachdenken.....
Wenn die Tabellen dieselbe Struktur haben, dann läuft die Suche analog
über jede Tabelle und kann beispielsweise mit einem Union zusammengefügt
werden.
Mit einem richtigen Index und den richtigen Datenzugriffen darf es kaum
einen spürbaren Unterschied geben, ob da 10'000 oder 60'000 Datensätze drin
sind. Das Auftrennen ist IMO überflüssig und zudem wird damit die
Normalisierung durchbrochen. Da allerdings scheinbar keine Beziehungen von
dieser Tabelle oder zu dieser Tabelle bestehen, ist es eh' irrelevant.

Gruss
Henry
--
Microsoft MVP Office Access
Keine E-Mails auf Postings in NGs. Danke.
Access FAQ www.donkarl.com
Lutz Uhlmann
2008-12-09 13:07:56 UTC
Permalink
Post by Henry Habermacher
Mit einem richtigen Index und den richtigen Datenzugriffen darf es kaum
einen spürbaren Unterschied geben, ob da 10'000 oder 60'000 Datensätze
drin sind. Das Auftrennen ist IMO überflüssig und zudem wird damit die
Normalisierung durchbrochen. Da allerdings scheinbar keine Beziehungen von
dieser Tabelle oder zu dieser Tabelle bestehen, ist es eh' irrelevant.
Angenommen meine BE liegt auf ner Netzwerk-Freigabe und ich greife über ne
Abfrage auf eine Tabelle mit X0.000 Datensätzen zu.
Wenn ich dort auf eine entsprechende Art und Weise (Wie?) Bedingungen für
z.B. nur 300 Datensätze stelle werden auch nur diese 300 Datensätze dieser
Tabelle übers Netz übertragen???
Ich war irgendwie immer der Meinung, daß Access die Daten ans Frontend
überträgt und erst dort eine entsprechende Filterung durchgeführt wird.

Lutz
Thomas Raasch
2008-12-09 14:03:54 UTC
Permalink
Hi
Post by Lutz Uhlmann
Angenommen meine BE liegt auf ner Netzwerk-Freigabe und ich greife über ne
Abfrage auf eine Tabelle mit X0.000 Datensätzen zu.
Wenn ich dort auf eine entsprechende Art und Weise (Wie?) Bedingungen für
z.B. nur 300 Datensätze stelle werden auch nur diese 300 Datensätze dieser
Tabelle übers Netz übertragen???
Ich war irgendwie immer der Meinung, daß Access die Daten ans Frontend
überträgt und erst dort eine entsprechende Filterung durchgeführt wird.
Jaaa genau so scheint es zu sein! Es werden immer alle Daten übertragen -
genau das ist ja mein Problem

was nebenbei erwähnt mit dieser Tabellentrennung tatsächlich umgangen werden
könnte

Grüße
Thomas
Jens Schilling
2008-12-09 14:15:43 UTC
Permalink
Hallo, Thomas
Post by Thomas Raasch
Jaaa genau so scheint es zu sein! Es werden immer alle Daten
übertragen - genau das ist ja mein Problem
Ich hab' mir jetzt nicht besonders viel Mühe gegegen, eine Quelle zu suchen,
die das exakt beschreibt, sondern habe mich schon mit diesem Statement von
Microsoft zufrieden gegeben, dass ich hier gefunden habe:

http://support.microsoft.com/kb/209126/en-us

Unter "Tips to improve query performance" ist bei "Note" nachzulesen:

[...] Access improves performance by requesting only the required records
from the server
--
Gruss
Jens
______________________________
FAQ: http://www.donkarl.com
Sascha Trowitzsch
2008-12-09 15:11:59 UTC
Permalink
Hi Thomas,
Post by Thomas Raasch
Hi
Post by Lutz Uhlmann
Angenommen meine BE liegt auf ner Netzwerk-Freigabe und ich greife über ne
Abfrage auf eine Tabelle mit X0.000 Datensätzen zu.
Wenn ich dort auf eine entsprechende Art und Weise (Wie?) Bedingungen für
z.B. nur 300 Datensätze stelle werden auch nur diese 300 Datensätze dieser
Tabelle übers Netz übertragen???
Ich war irgendwie immer der Meinung, daß Access die Daten ans Frontend
überträgt und erst dort eine entsprechende Filterung durchgeführt wird.
Jaaa genau so scheint es zu sein! Es werden immer alle Daten übertragen -
genau das ist ja mein Problem
Entschuldige, aber dein Problem ist eher, dass du etwas beratungsresistent bist.
Nun haben hier bereits etliche Access-Profis das Gegenteil behauptet und wenn du
dem Vorschlag von Josef, mal einen Showplan zu erzeugen, nachgegangen wärst,
dann könntest du dich auch selbst vom Gegenteil überzeugen.

Access sucht erst die Indizes, die zum Kriterium passen, vom Server und lädt
dann genau die Datensätze, die das Ergebnis erfordert - nicht mehr, nicht
weniger.
Wenn das bei dir anders ist, dann kann es nur entweder an fehlenden oder
falschen Primärschlüsseln liegen, bzw. an unzureichenden Indizes für die
Kriterienspalten, oder deine Server-Connection ist suboptimal oder der Server
macht nicht das, was er sollte (siehe Winfrieds Beitrag).
Dass Letzteres der Fall sein könnte, erscheint mir gar nicht mal
unwahrscheinlich, denn 60TSD Datensätze zu übertragen dauert normal keine 30
Sekunden. Das wären ja gerade 2000 DS pro Sekunde. Bei 100MBit-Netz (min. 2
MB/s) hieße das: 10000 Byte pro Datensatz! Wenn die Tabellen wirklich so gut
normalisiert wären, dann sind 10 kB pro Datensatz eindeutig zuviel.

Ciao, Sascha
Thomas Raasch
2008-12-09 15:47:21 UTC
Permalink
Hi,
Post by Sascha Trowitzsch
Hi Thomas,
Access sucht erst die Indizes, die zum Kriterium passen, vom Server und
lädt dann genau die Datensätze, die das Ergebnis erfordert - nicht mehr,
nicht weniger.
Jupp... muss ich nun auch bestätigen :)
Haben meine Tests nun endlich auch ergeben. War stets eine unglückliche
Kombination warum Access bei mir immer die komplette Tabelle holte.

bin am forschen....
JetShowPlan kann ich mir erst morgen vornehmen


Grüße und Danke für die Gedult
Thomas
Peter Doering
2008-12-08 13:41:36 UTC
Permalink
Hallo,
Post by Thomas Raasch
wir bauen Access-Progrämmchen für die Auftragsbearbeitung. Die Programme
sind bei manchen Kunden nun seit einigen Jahren im Einsatz. Das Format der
Access-Anwendung (FE) ist AccXP. Die reine Datenbank (BE) liegt ebenfalls
als AccXP vor. Die DB liegt idR. in einer Freigabe auf nem Windows-Server.
Das Netz ist zumeist nen 100MBit LAN.
Es häufen sich nun leider die Beschwerden, dass die Anwendung immer
das Öffnen eines Formulars (Inhalt: Aufträge) dauert schonmal gerne 30s. Die
DB hat 150 MB und die angesprochene Tabelle hat ca. 60.000 Datensätze. Laut
System-Überwachungs-Tools holt sich Access bei Formularstart die komplette
Tabelle mit allen 60.000 Datensätzen, wertet danach lokal am Client den
FilterBy und OrderBy aus und zeigt das Ergebnis an.
Das Ordern und Filtern geht dabei in Sekundenschnelle - aber das Übertragen
der Tabelle durchs LAN dauert....
30/22/18 sec. sind zu lang. Schau dir mal diese Seite an:
http://www.granite.ab.ca/access/performancefaq.htm

Ansonsten pruef mal, ob alle Tabellen an den richtigen Stellen indiziert
sind.

Gruss - Peter
--
Mitglied im http://www.dbdev.org
FAQ: http://www.donkarl.com
Thomas Raasch
2008-12-09 09:01:59 UTC
Permalink
Hi,
Post by Peter Doering
http://www.granite.ab.ca/access/performancefaq.htm
Ansonsten pruef mal, ob alle Tabellen an den richtigen Stellen indiziert
sind.
Jaaa das ist zu lang :)
Hab mir die Seite angesehen - habe die relevanten Tipps probiert jedoch ohne
Erfolg. Ebenfalls 0,0 Sek Unterschied. Vieles trifft aber auch schon zu wie
bspw. der 8.3-Dateiname oder kurze Pfad und nicht verschachtelt....


Schade
Aber auch hier bleibt das Problem, dass die komplette Tabelle übers LAN
geschaufelt wird. Daher sollte wohl mein Ziel sein, die DB-Größe zu
verringern.


Grüße
Thomas
Peter Doering
2008-12-09 10:02:49 UTC
Permalink
Hallo,
"Peter Doering" ...
Post by Peter Doering
http://www.granite.ab.ca/access/performancefaq.htm
Ansonsten pruef mal, ob alle Tabellen an den richtigen Stellen indiziert
sind.
Jaaa das ist zu lang :)
Hab mir die Seite angesehen - habe die relevanten Tipps probiert jedoch ohne
Erfolg. Ebenfalls 0,0 Sek Unterschied. Vieles trifft aber auch schon zu wie
bspw. der 8.3-Dateiname oder kurze Pfad und nicht verschachtelt....
Schade
Aber auch hier bleibt das Problem, dass die komplette Tabelle übers LAN
geschaufelt wird. Daher sollte wohl mein Ziel sein, die DB-Größe zu
verringern.
Pruef mal auch, ob das Formular auf Dynaset oder Snapshot steht. Letzteres
hat zur Folge, dass das komplette Recordset gelesen werden muss, was i.d.R.
nicht notwendig ist. Dynaset ist viel schneller.

Gruss- Peter
--
Mitglied im http://www.dbdev.org
FAQ: http://www.donkarl.com
Henry Habermacher
2008-12-09 10:25:02 UTC
Permalink
Hallo Peter
Post by Peter Doering
Pruef mal auch, ob das Formular auf Dynaset oder Snapshot steht. Letzteres
hat zur Folge, dass das komplette Recordset gelesen werden muss, was
i.d.R. nicht notwendig ist. Dynaset ist viel schneller.
Ich glaube, das hatten wir gestern schon. Oder hast Du ein Synch Problem?
;-)

Gruss
Henry
--
Microsoft MVP Office Access
Keine E-Mails auf Postings in NGs. Danke.
Access FAQ www.donkarl.com
Peter Doering
2008-12-09 10:55:16 UTC
Permalink
Hallo Henry,
Post by Henry Habermacher
Post by Peter Doering
Pruef mal auch, ob das Formular auf Dynaset oder Snapshot steht. Letzteres
hat zur Folge, dass das komplette Recordset gelesen werden muss, was
i.d.R. nicht notwendig ist. Dynaset ist viel schneller.
Ich glaube, das hatten wir gestern schon. Oder hast Du ein Synch Problem?
Quer gelesen ;-)

Gruss - Peter
--
Mitglied im http://www.dbdev.org
FAQ: http://www.donkarl.com
Josef Poetzl
2008-12-09 10:03:28 UTC
Permalink
Hallo!
Post by Thomas Raasch
Post by Peter Doering
http://www.granite.ab.ca/access/performancefaq.htm
Ansonsten pruef mal, ob alle Tabellen an den richtigen Stellen indiziert
sind.
Jaaa das ist zu lang :)
Hab mir die Seite angesehen - habe die relevanten Tipps probiert jedoch ohne
Erfolg. Ebenfalls 0,0 Sek Unterschied. Vieles trifft aber auch schon zu wie
bspw. der 8.3-Dateiname oder kurze Pfad und nicht verschachtelt....
Schade
Aber auch hier bleibt das Problem, dass die komplette Tabelle übers LAN
geschaufelt wird.
Dann dürfte die betroffene Abfrage keine Indizes verwenden. Imo sollte
Jet zuerst nur die Indizes übers Netz schaufeln und erst dann die
Daten abholen.
Wie sieht der Jet-Showplan aus?
Post by Thomas Raasch
Daher sollte wohl mein Ziel sein, die DB-Größe zu
verringern.
Wenn das Öffnen bereits so lange dauert: werden zu diesem Zeitpunkt
überhaupt Daten abgerufen? Es könnte vielleicht auch ein Virenscanner
das FE genau prüfen wollen.

Die üblichen Maßnahmen wie Vermeiden von ldb-locking usw. hast du
bestimmt schon berücksichtigt.

mfg
Josef
--
EPT: (Access Error Prevention Table) http://access.joposol.com/
FAQ: (Access-FAQ von Karl Donaubauer) http://www.donkarl.com/
Thomas Raasch
2008-12-09 10:50:37 UTC
Permalink
Hallo,

schnell zu Peter: Form ist auf Dynaset, Ja
Post by Josef Poetzl
Dann dürfte die betroffene Abfrage keine Indizes verwenden. Imo sollte
Jet zuerst nur die Indizes übers Netz schaufeln und erst dann die
Daten abholen.
also auf die Felder in der WHERE liegt nen Index (mit "Duplikate zulassen" -
was nicht anders geht)
das OrderBy-Feld ist auch indiziert ("ohne Duplikate")

Warum sollte sich Acc nur den Index holen? Da die DB nicht auf eigenen
Platten liegt kann Access hier keine Sektoren ansprechen und braucht dann
dennoch die gesamte Tabelle. Lokal kann das evtl. anders gehn - weiß ich
nicht
Post by Josef Poetzl
Wie sieht der Jet-Showplan aus?
uuuuuhh... was zum Hänker ist der Jet-Showplan :)
Post by Josef Poetzl
Wenn das Öffnen bereits so lange dauert: werden zu diesem Zeitpunkt
überhaupt Daten abgerufen? Es könnte vielleicht auch ein Virenscanner
das FE genau prüfen wollen.
Ja, laut LAN-Überwachung ist die Bandbreite die kompletten 30Sek bei 80%.
Virenscanner habe ich auch schon deaktiviert - ohne Erfolg
Post by Josef Poetzl
Die üblichen Maßnahmen wie Vermeiden von ldb-locking usw. hast du
bestimmt schon berücksichtigt.
Bin derzeit für die Tests als einziger Benutzer auf der DB drauf...



Tipp: einfach mal ne MDB auf ein Netzwerkshare legen und eine große Tabelle
öffnen. Dabei den TaskMgr an machen und die Netzwerklast ansehen.... dann
sieht man das Problem. Auch wenn Access schon ein Ergebnis anzeigt wird im
Hintergrund mächtig nachgeladen



Grüße
Thomas
Josef Poetzl
2008-12-09 11:06:29 UTC
Permalink
Hallo!
Post by Thomas Raasch
Post by Josef Poetzl
Wie sieht der Jet-Showplan aus?
uuuuuhh... was zum Hänker ist der Jet-Showplan :)
Der Ausführungsplan einer Jet-SQL-Abfrage.
.. sehr hilfreich ist das Tool "Showplan Capturer" von Sascha
Trowitzsch ( http://www.access-im-unternehmen.de/599.0.html )

lesenswert: AEK-Vortrag zum Thema "Abfrageoptimierung" von Michael
Zimmermann.
Post by Thomas Raasch
Post by Josef Poetzl
Die üblichen Maßnahmen wie Vermeiden von ldb-locking usw. hast du
bestimmt schon berücksichtigt.
Bin derzeit für die Tests als einziger Benutzer auf der DB drauf...
Na und?
Auch hier muss die ldb-Datei geprüft werden. (Was allerdings keine 30
sec. ausmachen wird.)
Post by Thomas Raasch
Tipp: einfach mal ne MDB auf ein Netzwerkshare legen und eine große Tabelle
öffnen. Dabei den TaskMgr an machen und die Netzwerklast ansehen.... dann
sieht man das Problem. Auch wenn Access schon ein Ergebnis anzeigt wird im
Hintergrund mächtig nachgeladen
Klar, weil alle Daten eingelesen werden, wenn man die Auswahl nicht
einschränkt.
Du meinst doch eine Tabelle in der Datenblattansicht öffnen, oder?

Im ersten Beitrag schreibst du aber von einem Filter.
=> öffne eine Abfrage mit Filter und prüfe ob dann auch alle Daten
geladen werden.


Zur Sicherheit noch einmal nachgefragt: das Feld nach dem gefiltert
wird ist in einem Index enthalten?


mfg
Josef
--
EPT: (Access Error Prevention Table) http://access.joposol.com/
FAQ: (Access-FAQ von Karl Donaubauer) http://www.donkarl.com/
Thomas Raasch
2008-12-09 14:09:05 UTC
Permalink
Hi,
Post by Josef Poetzl
Post by Thomas Raasch
Tipp: einfach mal ne MDB auf ein Netzwerkshare legen und eine große Tabelle
öffnen. Dabei den TaskMgr an machen und die Netzwerklast ansehen.... dann
sieht man das Problem. Auch wenn Access schon ein Ergebnis anzeigt wird im
Hintergrund mächtig nachgeladen
Klar, weil alle Daten eingelesen werden, wenn man die Auswahl nicht
einschränkt.
Du meinst doch eine Tabelle in der Datenblattansicht öffnen, oder?
egal
öffne ich ein Form mit tblAuftraege als DS-Herkunft dauert es 30 sek
öffne ich einfach nur die Tabelle zeigt Access quasi sofort ein Ergebnis
aber im Hintergrund wird weiterhin übertragen (genau 30 sek lang)
erst dann ist der letzte DS zugreifbar
öffne ich eine Abfrage "SELECT * FROM tblAufträge WHERE ID > 60000;"
passiert genau dasselbe - erst nach 30 sek kommt das Ergebnis!

könnt ihr alle sehr einfach mal überprüfen!
- LAN-Karte auf 10 MBit Half
- Große DB auf Netzfreigabe kopiert
- große DB/Tabelle öffnen (dabei TaskMgr an und Netzwerkstatistik anschauen)
Post by Josef Poetzl
Im ersten Beitrag schreibst du aber von einem Filter.
=> öffne eine Abfrage mit Filter und prüfe ob dann auch alle Daten
geladen werden.
Filter und Order haben keinerlei Einfluss auf die 30 Sek., da Access erst
die gesamte Tabelle rüberholt und dann im RAM in ca. 10ms Sortiert und
Filtert.
Post by Josef Poetzl
Zur Sicherheit noch einmal nachgefragt: das Feld nach dem gefiltert
wird ist in einem Index enthalten?
Jawoll :)


Grüße
Thomas
Thomas Raasch
2008-12-09 15:49:13 UTC
Permalink
Post by Thomas Raasch
egal
öffne ich ein Form mit tblAuftraege als DS-Herkunft dauert es 30 sek
öffne ich einfach nur die Tabelle zeigt Access quasi sofort ein Ergebnis
aber im Hintergrund wird weiterhin übertragen (genau 30 sek lang)
erst dann ist der letzte DS zugreifbar
öffne ich eine Abfrage "SELECT * FROM tblAufträge WHERE ID > 60000;"
passiert genau dasselbe - erst nach 30 sek kommt das Ergebnis!
Ich muss mich verbessern!
es liegt an einer Mischung als Filter - Order - Index und die Reihenfolge in
der was angewendet wird...

es geht also inzwischen auch bei mir schneller - nur nicht so wie ich es mir
wünsche...
Näheres ein paar Posts tiefer

Grüße
Sascha Trowitzsch
2008-12-09 14:57:46 UTC
Permalink
Hi,
Post by Josef Poetzl
Hallo!
Post by Thomas Raasch
Post by Josef Poetzl
Wie sieht der Jet-Showplan aus?
uuuuuhh... was zum Hänker ist der Jet-Showplan :)
Der Ausführungsplan einer Jet-SQL-Abfrage.
.. sehr hilfreich ist das Tool "Showplan Capturer" von Sascha
Trowitzsch ( http://www.access-im-unternehmen.de/599.0.html )
Wollte mal erwähnen, dass es von diesem Tool eine neue leicht geänderte Version
gibt:
http://www.moss-soft.de/public/showplan_v5.zip

Man kann nun das Log aus dem Tool heraus schnell mal in eine Textdatei
speichern - etwa um verschiedene Logs später zu analysieren.

Ciao, Sascha
Peter Doering
2008-12-09 11:27:46 UTC
Permalink
Hallo,
"Josef Poetzl" ...
Tipp: einfach mal ne MDB auf ein Netzwerkshare legen und eine große Tabelle
öffnen. Dabei den TaskMgr an machen und die Netzwerklast ansehen.... dann
sieht man das Problem. Auch wenn Access schon ein Ergebnis anzeigt wird im
Hintergrund mächtig nachgeladen
Ok, wir sollten mal klaeren, ob wir unter Laden das gleiche verstehen, bzw.
ob sich die gemessene Zeit auf die Anzeige oder das komplette Laden aller
DS bezieht. Letzteres darf ruhig laenger dauern. Das Formular muss nach
wenigen Sekunden (erfahrungsgemaess 1-2 sec.) zu sehen sein.

Gruss - Peter
--
Mitglied im http://www.dbdev.org
FAQ: http://www.donkarl.com
Henry Habermacher
2008-12-09 11:12:28 UTC
Permalink
Hallo Thomas
Post by Thomas Raasch
Warum sollte sich Acc nur den Index holen? Da die DB nicht auf eigenen
Platten liegt kann Access hier keine Sektoren ansprechen und braucht dann
dennoch die gesamte Tabelle. Lokal kann das evtl. anders gehn - weiß ich
nicht
Unsinn. Jet kennt doch die Struktur der eigenen Datei und wird genau diese
Pages der Datei anfordern die es für richtig hält, unabhängig davon, ob dies
eine lokale Platte oder ein Netzwerklaufwerk ist. Und der Windows Server
wird genau diese Pages lesen und abliefern. Jet muss u.U. nicht mal alle
Index Pages lesen, wenn der Index optimal liegt, sondern kann dann über die
Rushmore Technologie ziemlich schnell die richtigen Pages anfordern.
Gleiches übrigens beim Schreiben. Da schreibt Jet ja auch nur die Pages
zurück, die effektiv geändert haben, nicht einfach jedes Mal die ganze
Tabelle.
Post by Thomas Raasch
Post by Josef Poetzl
Wie sieht der Jet-Showplan aus?
uuuuuhh... was zum Hänker ist der Jet-Showplan :)
Schau' beim www.dbdev.org in den Download Bereich. Oder wirf mall Google
oder Live Search an.

Gruss
Henry
--
Microsoft MVP Office Access
Keine E-Mails auf Postings in NGs. Danke.
Access FAQ www.donkarl.com
Karl Donaubauer
2008-12-08 13:57:08 UTC
Permalink
...
Die DB hat 150 MB und die angesprochene Tabelle hat ca. 60.000
Datensätze. Laut System-Überwachungs-Tools holt sich Access bei
Formularstart die komplette Tabelle mit allen 60.000 Datensätzen,
wertet danach lokal am Client den FilterBy und OrderBy aus und zeigt
das Ergebnis an. Das Ordern und Filtern geht dabei in Sekundenschnelle -
aber das
Übertragen der Tabelle durchs LAN dauert....
Die Reduktion der übertragenen Daten wäre der wichtigste Schritt.

Falls du das Ordnen und Filtern mit den Formulareigenschaften machst,
dann versuch mal stattdessen eine Abfrage. Entscheidend dabei ist,
dass die Felder, nach denen du darin filterst, richtig indiziert sind.

Schau dir dazu auch mal Michaels AEK8-Skript an:
http://www.donkarl.com/AEK/AEKDownloads/AEK8_Abfragen_Performance.zip
--
HTH
Karl
********* Ich beantworte keine Access-Fragen per Email. *********
Access-FAQ: http://www.donkarl.com
Thomas Raasch
2008-12-09 09:13:43 UTC
Permalink
Hi
Post by Karl Donaubauer
Die Reduktion der übertragenen Daten wäre der wichtigste Schritt.
das vermute ich ja auch.. die Frage ist Wie?
Und daher ja meine beiden Vorschläge mit "Unicode-Komprimierung" und dem
Konvertieren in Acc97.
Gibt es hierbei Nachteile?
Weil die Datenmengen werden dadurch reduziert und es wird alles etwas
schneller...
Post by Karl Donaubauer
Falls du das Ordnen und Filtern mit den Formulareigenschaften machst,
dann versuch mal stattdessen eine Abfrage. Entscheidend dabei ist,
dass die Felder, nach denen du darin filterst, richtig indiziert sind.
http://www.donkarl.com/AEK/AEKDownloads/AEK8_Abfragen_Performance.zip
Also derzeit steht als Recordsource die Tabelle direkt drin. Per Code wird
beim Start dann Filter="xy" und OrderBy="yx" gesetzt. Hatte dies auch schon
fest eingetragen und auch schon entfernt - keine Änderung!
Beim Entfernen des Filter und Order ist zu beobachten, dass nach schon 3
Sekunden das Formular erscheint und den ersten DS anzeigt. Aber im
Hintergrund werden weiterhin die Daten übertragen... Die LAN-Auslastung ist
dabei ebenso 30 Sekunden lang auf Volldampf.
Auch wenn Access ohne Filter und Order schon nach 3 Sekunden etwas anzeigt,
so bleibt das Programm jedoch unbedienbar bis alle DSe geladen wurden.

Auch wenn ich eine Abfrage als DS-Herkunft nehme und den Filter/Order dort
fest reinschreibe bleibt die Zeit identisch.

Ich werde mir nun mal die ZIP anschauen..



Was kann man denn zu den Vor-/Nachteilen sagen von den beiden Varianten:
Unicode-Komprimierung und
Konvertierung zu Acc97
?


Grüße
Thomas
Henry Habermacher
2008-12-09 09:55:28 UTC
Permalink
Hallo Thomas
Post by Thomas Raasch
Post by Karl Donaubauer
Die Reduktion der übertragenen Daten wäre der wichtigste Schritt.
das vermute ich ja auch.. die Frage ist Wie?
Und daher ja meine beiden Vorschläge mit "Unicode-Komprimierung" und dem
Konvertieren in Acc97.
Gibt es hierbei Nachteile?
Weil die Datenmengen werden dadurch reduziert und es wird alles etwas
schneller...
Das wird kaum was bringen. Du musst an der Record Source des Formulars
schrauben. z.B. das Formular im Hinzufügen Modus öffnen, damit überhaupt
keine Daten eingelesen werden und dannach verlangen, dass ein vernünftiges
Filter gesetzt wird.

Ansonsten musst Du auch aufpassen, dass Du in der Record Source wirklich nur
die Felder drin hast, die Du im Formular anzeigst. Ein "Select * FROM
DeineTabelle" oder sogar "DeineTabelle" als Record Source kann durchaus
verheerende Folgen wie von Dir beschrieben haben, wenn dort z.B. grosse
Memofelder oder OLE Objekte in der Tabelle drin sind, die Du auf dem
Formular gar nicht anzeigst.
Post by Thomas Raasch
Also derzeit steht als Recordsource die Tabelle direkt drin. Per Code wird
beim Start dann Filter="xy" und OrderBy="yx" gesetzt. Hatte dies auch
schon fest eingetragen und auch schon entfernt - keine Änderung!
Das kann kaum sein. Trag mal als Recordsource des Formulars "SELECT ... FROM
DeineTabelle WHERE DeinFeld = 'xy' ORDER BY .. , statt den Filter und die
Sortierung im Formular festzulegen. Und dann noch sicherstellen, dass Du
über DeinFeld und die Felder im Order By ein Index hast, damit die Daten in
der richtigen Reihenfolge gelesen und gleich gefiltert ausgelesen werden
können, ohne dass die ganze Tabelle zuerst lokal in den Temporären Speicher
eingelesen werden muss. Genaueres erfährst Du, wenn Du JetShowPlan
einschaltest. Siehe diesbezüglich im Downloadbereich des www.dbdev.org nach.
Post by Thomas Raasch
Unicode-Komprimierung und
Konvertierung zu Acc97
?
Die Unicode Komprimierung auszuschalten ist sicher der falsche Weg, weil
dann noch mehr Daten von der Tabelle über das Netzwerk eingelesen werden
müssen.

Auf das Acc97 Formuat zu setzen ist IMO auch der falsche weg, weil Acc97
keinen Unicode unterstützt. Zudem gehen Dir dann einige Features ab, die
erst mit Jet 4 eingeführt wurden. Frag' mich aber nicht, welche das sind,
die dann fehlen, wenn nur die BE im 3.5-er Format vorliegt.

Gruss
Henry
--
Microsoft MVP Office Access
Keine E-Mails auf Postings in NGs. Danke.
Access FAQ www.donkarl.com
Thomas Raasch
2008-12-09 10:59:56 UTC
Permalink
Hi,
Post by Henry Habermacher
Post by Thomas Raasch
Weil die Datenmengen werden dadurch reduziert und es wird alles etwas
schneller...
Das wird kaum was bringen. Du musst an der Record Source des Formulars
schrauben. z.B. das Formular im Hinzufügen Modus öffnen, damit überhaupt
keine Daten eingelesen werden und dannach verlangen, dass ein vernünftiges
Filter gesetzt wird.
ich sehe keine andere Möglichkeit... Selbst wenn ich im AddNew-Modus öffne
(das geht wunderbar schnell) und dann einen Filter setzt so warte ich eben
ab dann 30 Sek. weil er eben erst dann alle 60.000 DS überträgt
Ein Filter wird meines Erachtens nach bei Access immer erst lokal
angewendet! Ich _glaube_ Access holt sich immer die komplette Tab und macht
dann lokal im Nachhinein den Filter
Da kann ich also an Indexen und Abfragen drehen wie ich will....
Post by Henry Habermacher
Ansonsten musst Du auch aufpassen, dass Du in der Record Source wirklich
nur die Felder drin hast, die Du im Formular anzeigst. Ein "Select * FROM
DeineTabelle" oder sogar "DeineTabelle" als Record Source kann durchaus
verheerende Folgen wie von Dir beschrieben haben, wenn dort z.B. grosse
Memofelder oder OLE Objekte in der Tabelle drin sind, die Du auf dem
Formular gar nicht anzeigst.
Memo und OLE verwende ich gar nicht
Maximal Text(255) und der wird als VARCHAR gespeichert
Da kann man nichts mehr optimieren... und SELECT * ist es, aber ich brauche
auch alle Felder :)
Post by Henry Habermacher
Post by Thomas Raasch
Also derzeit steht als Recordsource die Tabelle direkt drin. Per Code wird
beim Start dann Filter="xy" und OrderBy="yx" gesetzt. Hatte dies auch
schon fest eingetragen und auch schon entfernt - keine Änderung!
Das kann kaum sein. Trag mal als Recordsource des Formulars "SELECT ...
FROM DeineTabelle WHERE DeinFeld = 'xy' ORDER BY .. , statt den Filter und
die Sortierung im Formular festzulegen. Und dann noch sicherstellen, dass
Du über DeinFeld und die Felder im Order By ein Index hast, damit die
Daten in der richtigen Reihenfolge gelesen und gleich gefiltert ausgelesen
werden können, ohne dass die ganze Tabelle zuerst lokal in den Temporären
Speicher eingelesen werden muss. Genaueres erfährst Du, wenn Du
JetShowPlan einschaltest. Siehe diesbezüglich im Downloadbereich des
www.dbdev.org nach.
Da ist es wieder... dieses JetShowPlan :)
Ich werds mir mal antun!
Den Filter und Order hatte ich bereits direkt in der DS-Herkunft des
Formulars - identische Zeit - identische Datenbewegung übers LAN
Post by Henry Habermacher
Post by Thomas Raasch
Unicode-Komprimierung und
Konvertierung zu Acc97
?
Die Unicode Komprimierung auszuschalten ist sicher der falsche Weg, weil
dann noch mehr Daten von der Tabelle über das Netzwerk eingelesen werden
müssen.
woooos???? Also mit aktivierter Unicode-Komp. war die DB sofort einige MB
kleiner! Ergo. es muss weniger übertragen werden und so war es ja dann auch.
Durch Komp. startete das Form schneller bzw. war die LAN-Last schneller
wieder unten.
Bist Du Dir bei Deiner Aussage sicher???
Post by Henry Habermacher
Auf das Acc97 Formuat zu setzen ist IMO auch der falsche weg, weil Acc97
keinen Unicode unterstützt. Zudem gehen Dir dann einige Features ab, die
erst mit Jet 4 eingeführt wurden. Frag' mich aber nicht, welche das sind,
die dann fehlen, wenn nur die BE im 3.5-er Format vorliegt.
Joo, genau. Verlust von Features. Wäre jetzt gut zu wissen welche :)
Vermutlich kann ich darauf gern verzichten

Grüße
Thomas
Henry Habermacher
2008-12-08 14:14:43 UTC
Permalink
Hallo Thomas
Post by Thomas Raasch
das Öffnen eines Formulars (Inhalt: Aufträge) dauert schonmal gerne 30s.
Die DB hat 150 MB und die angesprochene Tabelle hat ca. 60.000
Datensätze. Laut System-Überwachungs-Tools holt sich Access bei
Formularstart die komplette Tabelle mit allen 60.000 Datensätzen, wertet
danach lokal am Client den FilterBy und OrderBy aus und zeigt das
Ergebnis an.
Hier musst Du ansetzen und nicht bei der Version und sogar noch auf alte,
nicht mehr supportete VErsionen zurückmigrieren.

Was steht in der Recordsource des Formulars drin? Ist da evt. die ganze
Tabelle drin? Was wird angezeigt, wenn das Formular geöffnet wird? Alle
Datensätze in einer Listenform?
Ich schlage folgendes vor: Stelle statt der bisherigen Recordsource eine
gefilterte Recordsource ein. Verpasse dem Formular die Möglichkeit, zu
filtern und lass dann die Benutzer den Filter ändern. Wenn Du nun nur 30
Sätze einlesen musst, statt deren 60'000 dann ist das massiv schneller,
unabhängig vom Datenbankformat.
Des weiteren: Stelle sicher, dass der Recordset Type des Formulares auf
Dynaset gesetzt ist, nicht auf Snapshot, auch wenn das Formular selber keine
Updates zulässt. Snapshots verursachen, dass immer die komplette Datenquelle
in einem Aufwisch geholt werden muss, damit der Snapshot in sich konsistent
ist. Beim Dynaset sollte das Formular nur gerade die Datensätze holen, die
es gerade anzeigen muss, allenfalls noch ein paar mehr.

Gruss
Henry
--
Microsoft MVP Office Access
Keine E-Mails auf Postings in NGs. Danke.
Access FAQ www.donkarl.com
Olaf O.
2008-12-08 16:04:01 UTC
Permalink
Hi!

Entferne eventuell vorhandene Nachschlagefelder in der Tabelle.
Setze zudem in den Tabelleneigenschaften Unterdatenblattname auf [keines]
Thomas Raasch
2008-12-09 10:32:23 UTC
Permalink
Hi,
Post by Henry Habermacher
Was steht in der Recordsource des Formulars drin? Ist da evt. die ganze
Tabelle drin? Was wird angezeigt, wenn das Formular geöffnet wird? Alle
Datensätze in einer Listenform?
RecordSource ist die Tabelle direkt... also einfach tblAuftraege
Das Formular ist ein normales Formular - ein sogenanntes "Einzelnes
Formular"
Die Tabelle steht in keinerlei Beziehung. Also es gibt bspw. keine
Auftragspositionen oder sonstwas... keine Joins - nix
Wenn das Form geöffnet wird kommt (mit Filter/Order) 30Sek gar nichts und
dann ist es schwups einfach da
Ohne Filter/Order erscheint das Form nach ca. 3Sek bleibt aber relativ
unbedienbar bis die gesamte Datenmenge durchs LAN geschaufelt ist. (was
besagte 30 Sek dauert)
"relative unbedienbar" heißt, dass es bspw. nicht möglich ist einen neuen DS
anzulegen...
Post by Henry Habermacher
Ich schlage folgendes vor: Stelle statt der bisherigen Recordsource eine
gefilterte Recordsource ein. Verpasse dem Formular die Möglichkeit, zu
filtern und lass dann die Benutzer den Filter ändern. Wenn Du nun nur 30
Sätze einlesen musst, statt deren 60'000 dann ist das massiv schneller,
unabhängig vom Datenbankformat.
Wenn ich Access richtig verstanden habe macht dies keinen Unterschied! Wenn
die DB auf einem Netzlaufwerk liegt holt sich Acc immer die komplette
Tabelle und wertet dann nur lokal beim Client die WHERE aus... quasi im RAM
Ich brauche nur einen Filter ala "WHERE Anzahl > AnzahlGeliefert"
Von den 60.000 bleiben damit ca. 200 über die angezeigt werden (nachdem
_alle_ 60.000 durch Netz geschickt wurden)
Post by Henry Habermacher
Des weiteren: Stelle sicher, dass der Recordset Type des Formulares auf
Dynaset gesetzt ist, nicht auf Snapshot, auch wenn das Formular selber keine
ja war/ist Dynaset




Grüße
Thomas
Josef Poetzl
2008-12-09 10:46:54 UTC
Permalink
Hallo!
Post by Thomas Raasch
Post by Henry Habermacher
Ich schlage folgendes vor: Stelle statt der bisherigen Recordsource eine
gefilterte Recordsource ein. Verpasse dem Formular die Möglichkeit, zu
filtern und lass dann die Benutzer den Filter ändern. Wenn Du nun nur 30
Sätze einlesen musst, statt deren 60'000 dann ist das massiv schneller,
unabhängig vom Datenbankformat.
Wenn ich Access richtig verstanden habe macht dies keinen Unterschied!
Probiere es trotzdem aus. Access kann Indizes nutzen, wenn welche
vorhanden sind und der Filter indexfreundlich geschrieben wurde.
(Me.Filter bzw. where im SQL-Teil sollte normalerweise das gleiche
Ergebnis liefern. Möglicherweise ist aber das interne Vorgehen bei
Form.Filter etwas anders als bei einer gefilterten Datenherkunft.)

Du schreibst, dass bei nicht gesetztem Form-Filter und Form-OrderBy
das Formular schnell lädt. Das ist möglich, da in diesem Fall die
Daten vermutlich unsortiert (bzw. gemäß PK sortiert) eingelesen
werden. Somit ist keine Auswertung über alle Datensätze erforderlich.

Stellst du z.b. keinen Filter aber Order By ein, müssen die
vorhandenen DS ausgewertet werden. Ob Jet hier einen Index nutzt weiß
ich nicht. Ich würde das zwar erwarten, aber trotzdem mit dem
Jet-Showplan prüfen, ob das der Fall ist. ;-)

Filterst du die DS über ein indiziertes Feld, sollten erstmal nur die
Werte aus dem Index gefiltert werden und dann der Rest der Daten für
das Formular abgeholt werden.

mfg
Josef
--
EPT: (Access Error Prevention Table) http://access.joposol.com/
FAQ: (Access-FAQ von Karl Donaubauer) http://www.donkarl.com/
Henry Habermacher
2008-12-09 11:07:01 UTC
Permalink
Hallo Thomas
Post by Thomas Raasch
Post by Henry Habermacher
Ich schlage folgendes vor: Stelle statt der bisherigen Recordsource eine
gefilterte Recordsource ein. Verpasse dem Formular die Möglichkeit, zu
filtern und lass dann die Benutzer den Filter ändern. Wenn Du nun nur 30
Sätze einlesen musst, statt deren 60'000 dann ist das massiv schneller,
unabhängig vom Datenbankformat.
Wenn ich Access richtig verstanden habe macht dies keinen Unterschied!
Wenn die DB auf einem Netzlaufwerk liegt holt sich Acc immer die komplette
Tabelle und wertet dann nur lokal beim Client die WHERE aus... quasi im
RAM Ich brauche nur einen Filter ala "WHERE Anzahl > AnzahlGeliefert"
Von den 60.000 bleiben damit ca. 200 über die angezeigt werden (nachdem
_alle_ 60.000 durch Netz geschickt wurden)
Unsinn, da hast Du Access falsch verstanden. Access liest, wenn es indices
gibt, hoffentlich nur die Pages, in denen die DAtetnsätze drin stehen, die
es braucht, nicht einfach immer alles. Stell Dir mal vor wie das ausgehen
würde, wenn eine Tabelle mal so 500 MByte gross geworden ist. Nein, ganz so
dumm ist Access nun auch wieder nicht.

Versuch's doch einfach mal. Leg' zuerst einen Index über das Feld Anzahl,
und öffne dann das Formular mit einer Where Bedingung, in welcher Du dann
z.B. Anzahl Gefiltert auf einen Wert stellst, bei dem nicht mehr viel
angezeigt wird.

Gruss
Henry
--
Microsoft MVP Office Access
Keine E-Mails auf Postings in NGs. Danke.
Access FAQ www.donkarl.com
Josef Poetzl
2008-12-09 11:34:02 UTC
Permalink
Hallo!
Post by Henry Habermacher
Post by Thomas Raasch
Ich brauche nur einen Filter ala "WHERE Anzahl > AnzahlGeliefert"
Von den 60.000 bleiben damit ca. 200 über die angezeigt werden (nachdem
_alle_ 60.000 durch Netz geschickt wurden)
[...]
Post by Henry Habermacher
Versuch's doch einfach mal. Leg' zuerst einen Index über das Feld Anzahl,
und öffne dann das Formular mit einer Where Bedingung, in welcher Du dann
z.B. Anzahl Gefiltert auf einen Wert stellst, bei dem nicht mehr viel
angezeigt wird.
Hier versteckt sich vermutlich das Problem. Ich vermute, dass Anzahl
(=AnzahlBestellt?) und AnzahlGeliefert Datenfelder von einem DS sind.
Damit ist ein Table scan erforderlich.

So gesehen wäre es besser, in der Tabelle ein Datenfeld "AnzahlOffen"
zu führen. Dann könnte mit der Bedingung "... where AnzahlOffen > 0"
ein Index genutzt werden.

mfg
Josef
--
EPT: (Access Error Prevention Table) http://access.joposol.com/
FAQ: (Access-FAQ von Karl Donaubauer) http://www.donkarl.com/
Henry Habermacher
2008-12-09 12:05:31 UTC
Permalink
Hallo Josef
Post by Josef Poetzl
Post by Henry Habermacher
Post by Thomas Raasch
Ich brauche nur einen Filter ala "WHERE Anzahl > AnzahlGeliefert"
Von den 60.000 bleiben damit ca. 200 über die angezeigt werden (nachdem
_alle_ 60.000 durch Netz geschickt wurden)
[...]
Post by Henry Habermacher
Versuch's doch einfach mal. Leg' zuerst einen Index über das Feld Anzahl,
und öffne dann das Formular mit einer Where Bedingung, in welcher Du dann
z.B. Anzahl Gefiltert auf einen Wert stellst, bei dem nicht mehr viel
angezeigt wird.
Hier versteckt sich vermutlich das Problem. Ich vermute, dass Anzahl
(=AnzahlBestellt?) und AnzahlGeliefert Datenfelder von einem DS sind.
Damit ist ein Table scan erforderlich.
Muss nicht sein, bei einem richtig angelegten Index über die Felder Anzahl
und AnzahlGeliefert, kann diese Where Bedingung alleine vom Index her
aufgelöst werden. Es müssen aber ziemlich sicher alle Index Pages
durchlaufen werden.
Post by Josef Poetzl
So gesehen wäre es besser, in der Tabelle ein Datenfeld "AnzahlOffen"
zu führen. Dann könnte mit der Bedingung "... where AnzahlOffen > 0"
ein Index genutzt werden.
siehe oben

Gruss
Henry
--
Microsoft MVP Office Access
Keine E-Mails auf Postings in NGs. Danke.
Access FAQ www.donkarl.com
Thomas Raasch
2008-12-09 14:54:29 UTC
Permalink
Hallo,

wir kommen dem Ziel Näher!
Post by Henry Habermacher
Post by Josef Poetzl
Post by Thomas Raasch
Ich brauche nur einen Filter ala "WHERE Anzahl > AnzahlGeliefert"
Hier versteckt sich vermutlich das Problem. Ich vermute, dass Anzahl
(=AnzahlBestellt?) und AnzahlGeliefert Datenfelder von einem DS sind.
Damit ist ein Table scan erforderlich.
Jaaa, so scheint es zu sein
Ich habe einiges versucht und es war stets eine unglückliche Verkettung von
Zufällen weshalb ich nicht drauf gekommen bin.
Folgendes gibts nun zu berichten:
DS-Herkunft = tblAuftraege
Filter = leer
Order = lerr
per Code wird im Form beim Start der Filter = "Anazhl > AnzahlGeliefert"
gesetzt
per Code wird die OrderBy gesetzt

Ändere ich den Filter auf "Anzahl > 10.000", so umfasst das Ergebnis nur
noch rund 100 DS. Diese kommen dann tatsächlich auch in 1-2 Sekunden an! Es
funktioniert also (plötzlich). Ein Problem war bisher, dass das OrderBy vor
dem Filter gesetzt wurde. Wie das da im Code nach oben rücken konnte ist mir
noch unklar. Weil dann gehts (verständlicherweise) nicht.

Erzeuge ich also einen Filter mit Anzahl > 10000 so gehts schnell
prüfe ich Anzahl > AnzahlGeliefert dauerts...
scheinbar ist also die Vermutung von Josef mit dem TableScan korrekt...
Post by Henry Habermacher
Muss nicht sein, bei einem richtig angelegten Index über die Felder Anzahl
und AnzahlGeliefert, kann diese Where Bedingung alleine vom Index her
aufgelöst werden. Es müssen aber ziemlich sicher alle Index Pages
durchlaufen werden.
Aha... wie was wo? :)
Ich habe beide Felder getrennt von einander indiziert
beide einfach per Index --> Ja, (ohne Duplikate)
Post by Henry Habermacher
Post by Josef Poetzl
So gesehen wäre es besser, in der Tabelle ein Datenfeld "AnzahlOffen"
zu führen. Dann könnte mit der Bedingung "... where AnzahlOffen > 0"
ein Index genutzt werden.
Das wäre die Ausweich-Option.
Jedoch bin ich gespannt, wie ein "richtiger" Index aussehen soll.
Und wenn dieser steht bin ich gespannt
a) obs geht
b) warum dasselbe Problem auch bei Lieferscheinen, Rechnungen, Angebote,
Bestellungen, Artikel, usw. vorliegt

aber da komme ich dann schon dahinter!


Grüße
Thomas
Josef Poetzl
2008-12-09 18:02:56 UTC
Permalink
Hallo!
Post by Thomas Raasch
Post by Henry Habermacher
Post by Josef Poetzl
Post by Thomas Raasch
Ich brauche nur einen Filter ala "WHERE Anzahl > AnzahlGeliefert"
Hier versteckt sich vermutlich das Problem. Ich vermute, dass Anzahl
(=AnzahlBestellt?) und AnzahlGeliefert Datenfelder von einem DS sind.
Damit ist ein Table scan erforderlich.
Jaaa, so scheint es zu sein
Ich habe einiges versucht und es war stets eine unglückliche Verkettung von
Zufällen weshalb ich nicht drauf gekommen bin.
daher in Zukunft immer den Jet-Showplan befragen. ;-)

[...]
Post by Thomas Raasch
Post by Henry Habermacher
Muss nicht sein, bei einem richtig angelegten Index über die Felder Anzahl
und AnzahlGeliefert, kann diese Where Bedingung alleine vom Index her
aufgelöst werden. Es müssen aber ziemlich sicher alle Index Pages
durchlaufen werden.
Wenn überhaupt.
Post by Thomas Raasch
Aha... wie was wo? :)
Ich habe beide Felder getrennt von einander indiziert
beide einfach per Index --> Ja, (ohne Duplikate)
Ich teste eine Tab mit 2 Mio DS und einem 2-Felder-Index:
SELECT id, AnzahlBestellt, AnzahlGeliefert
FROM tabBestellpositionen
WHERE AnzahlGeliefert < AnzahlBestellt And AnzahlGeliefert > 0
order by AnzahlBestellt

=>
01) Restrict rows of table tabBestellpositionen
using rushmore
for expression "AnzahlGeliefert>0"
then test expression "AnzahlGeliefert<AnzahlBestellt"
02) Sort result of '01)'


für AnzahlGeliefert>0 wird der Index anscheinend genutzt, da rushmore
verwendet wird. Ob der Vergleich AnzahlGeliefert<AnzahlBestellt mit
den Index-Feldern abläuft kann ich unter jet nicht beurteilen.
Post by Thomas Raasch
Post by Henry Habermacher
Post by Josef Poetzl
So gesehen wäre es besser, in der Tabelle ein Datenfeld "AnzahlOffen"
zu führen. Dann könnte mit der Bedingung "... where AnzahlOffen > 0"
ein Index genutzt werden.
Das wäre die Ausweich-Option.
Jedoch bin ich gespannt, wie ein "richtiger" Index aussehen soll.
Eine schnellere Version als mit "AnzahlOffen > 0" wirst du nie
erreichen. Im Prinzip müsste du dafür aber die Datenerfassung
umstellen. Statt der Liefermenge immer die Restmenge abspeichern und
die Liefermenge berechnen.

[OT]
Ist es eigentlich Absicht, dass keine Teillieferungen gespeichert
werden?
[/OT]
Post by Thomas Raasch
Und wenn dieser steht bin ich gespannt
a) obs geht
b) warum dasselbe Problem auch bei Lieferscheinen, Rechnungen, Angebote,
Bestellungen, Artikel, usw. vorliegt
Es wird vermutlich immer das gleiche Problem sein: Ein Filterausdruck,
der einen table scan auslöst.


mfg
Josef
--
EPT: (Access Error Prevention Table) http://access.joposol.com/
FAQ: (Access-FAQ von Karl Donaubauer) http://www.donkarl.com/
Thomas Möller
2008-12-09 20:40:21 UTC
Permalink
Hallo Thomas,
Post by Thomas Raasch
Jaaa, so scheint es zu sein
Ich habe einiges versucht und es war stets eine unglückliche Verkettung von
Zufällen weshalb ich nicht drauf gekommen bin.
DS-Herkunft = tblAuftraege
Filter = leer
Order = lerr
per Code wird im Form beim Start der Filter = "Anazhl > AnzahlGeliefert"
gesetzt
per Code wird die OrderBy gesetzt
auch wenn das hier nicht die Ursache des Problems zu sein scheint, Du
solltest das Feld "Anzahl" dringend umbenennen. Anzahl ist die deutsche
Übersetzung eines in Access reservierten Wortes (Count).
Schau zu diesem Thema auch hier:
www.donkarl.com?FAQ1.5
(Link in einer Zeile)
Post by Thomas Raasch
Ändere ich den Filter auf "Anzahl > 10.000", so umfasst das Ergebnis nur
noch rund 100 DS. Diese kommen dann tatsächlich auch in 1-2 Sekunden an! Es
funktioniert also (plötzlich). Ein Problem war bisher, dass das OrderBy vor
dem Filter gesetzt wurde. Wie das da im Code nach oben rücken konnte ist mir
noch unklar. Weil dann gehts (verständlicherweise) nicht.
zeig doch bitte mal Deinen Code. Ich könnte mir nämlich vorstellen, dass
u.U. die Daten zwei mal abgerufen werden. Einmal nach dem Setzen des
OrderBy und einmal nach dem Setzen des Filters.

Wie wäre es, wenn Du statt dessen eine einfach Abfrage verwendest:

SELECT * FROM DeineTabelle
WHERE Anzahl > AnzahlGeliefert
ORDER BY DeinFeld

Wird eigentlich immer nach dem selben Feld sortiert? Dann brauchst Du
die Abfrage nicht einmal anpassen.
Post by Thomas Raasch
Post by Henry Habermacher
Muss nicht sein, bei einem richtig angelegten Index über die Felder Anzahl
und AnzahlGeliefert, kann diese Where Bedingung alleine vom Index her
aufgelöst werden. Es müssen aber ziemlich sicher alle Index Pages
durchlaufen werden.
Aha... wie was wo? :)
Ich habe beide Felder getrennt von einander indiziert
beide einfach per Index --> Ja, (ohne Duplikate)
Der Einsatz eines solchen Indexes würde bedeuten, dass die Anzahl in
zwei DS nicht den gleichen Wert annehmen kann. Ist das wirklich so gewollt?



CU
--
Thomas

Homepage: www.Team-Moeller.de
Thomas Raasch
2008-12-10 08:51:07 UTC
Permalink
Post by Thomas Möller
auch wenn das hier nicht die Ursache des Problems zu sein scheint, Du
solltest das Feld "Anzahl" dringend umbenennen. Anzahl ist die deutsche
Übersetzung eines in Access reservierten Wortes (Count).
www.donkarl.com?FAQ1.5
(Link in einer Zeile)
Jooo, klaro :)
die Felder haben alle einen Präfix. Die Anzahl heißt in den Aufträgen
"aufAnzahl" und in den Rechnungen "recAnzahl"
von daher gibts da keine Probleme... wir haben auch nen Feld "Summe" und
weitere - auch wieder mit Präfix davor
Post by Thomas Möller
zeig doch bitte mal Deinen Code. Ich könnte mir nämlich vorstellen, dass
u.U. die Daten zwei mal abgerufen werden. Einmal nach dem Setzen des
OrderBy und einmal nach dem Setzen des Filters.
Private Sub Form_Open(Cancel As Integer)
subFormOpen Me 'setzt Form-Eigenschaften wie
Löschen=Nein, Bearbeiten=Nein, ...

Me.Filter = "aufAnzahl > aufAnzahlGeliefert"
Me.FilterOn = True

Me.OrderBy = "aufNummer"

If Me.RecordsetClone.RecordCount = 0 Then
Me.FilterOn = False
End If

subView 'setzt einzelne Steuerelemente ggf.
auf unsichtbar
End Sub
Post by Thomas Möller
SELECT * FROM DeineTabelle
WHERE Anzahl > AnzahlGeliefert
ORDER BY DeinFeld
das brachte nun keine weiteren Veränderungen in der Geschwindigkeit... da
scheint Access schlau genug zu sein :)
Aber das Neu-Filtern von außen ist mit "Me.Filter = xy" einfacher
Post by Thomas Möller
Wird eigentlich immer nach dem selben Feld sortiert? Dann brauchst Du die
Abfrage nicht einmal anpassen.
Nööö sortiert wird immer mal anders.
Post by Thomas Möller
Post by Thomas Raasch
Aha... wie was wo? :)
Ich habe beide Felder getrennt von einander indiziert
beide einfach per Index --> Ja, (ohne Duplikate)
Der Einsatz eines solchen Indexes würde bedeuten, dass die Anzahl in zwei
DS nicht den gleichen Wert annehmen kann. Ist das wirklich so gewollt?
Ohhh ja vertippt! "mit Dupli." natürlich





Grüße
Thomas
Henry Habermacher
2008-12-10 03:25:56 UTC
Permalink
Hallo Thomas
Post by Thomas Raasch
Post by Henry Habermacher
Muss nicht sein, bei einem richtig angelegten Index über die Felder
Anzahl und AnzahlGeliefert, kann diese Where Bedingung alleine vom Index
her aufgelöst werden. Es müssen aber ziemlich sicher alle Index Pages
durchlaufen werden.
Aha... wie was wo? :)
Ich habe beide Felder getrennt von einander indiziert
beide einfach per Index --> Ja, (ohne Duplikate)
Leg einfach einen Mehrfeld Index an:
CREATE INDEX MehrFeldIndex ON DeineTabelle([Anzahl], [AnzahlGeliefert])

oder in der Entwicklungsumgebung indem Du dort die Indices anzeigen lässt
und dann einen neuen erfasst, bei dem Du in der ersten Zeile den Namen
angibst und dann das Namensfeld für die weiteren Indexfelder leer lässt.

Gruss
Henry
--
Microsoft MVP Office Access
Keine E-Mails auf Postings in NGs. Danke.
Access FAQ www.donkarl.com
Thomas Raasch
2008-12-10 09:28:55 UTC
Permalink
Hallo,
Post by Henry Habermacher
CREATE INDEX MehrFeldIndex ON DeineTabelle([Anzahl], [AnzahlGeliefert])
oder in der Entwicklungsumgebung indem Du dort die Indices anzeigen lässt
und dann einen neuen erfasst, bei dem Du in der ersten Zeile den Namen
angibst und dann das Namensfeld für die weiteren Indexfelder leer lässt.
das sagt JSP

01) Restrict rows of table tblAuftraege
by scanning
testing expression "aufAnzahl>aufAnzahlGeliefert"

:-( "by scanning"

der Index sieht so aus:
CREATE INDEX idxAnzahl ON tblAuftraege(aufAnzahl, aufAnzahlGeliefert)



Hüüüülfe!

Thomas
Henry Habermacher
2008-12-10 09:40:24 UTC
Permalink
Hallo Thomas
Post by Thomas Raasch
das sagt JSP
01) Restrict rows of table tblAuftraege
by scanning
testing expression "aufAnzahl>aufAnzahlGeliefert"
:-( "by scanning"
CREATE INDEX idxAnzahl ON tblAuftraege(aufAnzahl, aufAnzahlGeliefert)
Und hast Du anschliessend die Datenbank komprimiert, damit die Statistiken
aktualisiert werden? Falls nicht, mach' das und versuche es erneut.
Wenn das nichts nützt, dann lösche obigen Index wieder und lege einen über
aufAnzahl und einen über aufAnzahlGeliefert an, also zwei Indices,
komprimiere die Datenbank und versuche es erneut.
Wenn es immer noch einen Tablescan gibt, dann schlage ich folgendes vor:

1. ein neues Feld AnzDiff hinzufügen
2. AnzDiff über einen Update aktualisieren:
UPDATE tblAuftraege SET AnzDiff = aufAnzahl - aufAnzahlGeliefert
3. Index über AnzDiff anlegen
4. WHERE Bedingung so machen: "AnzDiff > 0"

Das sollte ziemlich flugs gehen.

Gruss
Henry
--
Microsoft MVP Office Access
Keine E-Mails auf Postings in NGs. Danke.
Access FAQ www.donkarl.com
Josef Poetzl
2008-12-10 10:12:24 UTC
Permalink
Hallo!
Post by Henry Habermacher
Post by Thomas Raasch
das sagt JSP
[OT]
gestern kannte Thomas den Jet-Showplan noch nicht und heute spricht er
ihn schon abgekürzt mi "JSP" an. :-))
[/OT]
Post by Henry Habermacher
Post by Thomas Raasch
01) Restrict rows of table tblAuftraege
by scanning
testing expression "aufAnzahl>aufAnzahlGeliefert"
:-( "by scanning"
CREATE INDEX idxAnzahl ON tblAuftraege(aufAnzahl, aufAnzahlGeliefert)
Und hast Du anschliessend die Datenbank komprimiert, damit die Statistiken
aktualisiert werden? Falls nicht, mach' das und versuche es erneut.
Wenn das nichts nützt, dann lösche obigen Index wieder und lege einen über
aufAnzahl und einen über aufAnzahlGeliefert an, also zwei Indices,
komprimiere die Datenbank und versuche es erneut.
Würde der Jet-Showplan überhaupt Auskunft geben, wenn ein Index-Scan
erfolgt?


mfg
Josef
--
EPT: (Access Error Prevention Table) http://access.joposol.com/
FAQ: (Access-FAQ von Karl Donaubauer) http://www.donkarl.com/
Henry Habermacher
2008-12-10 10:22:02 UTC
Permalink
Hallo Josef
Post by Josef Poetzl
Würde der Jet-Showplan überhaupt Auskunft geben, wenn ein Index-Scan
erfolgt?
Ich denke schon. Ein TAblescan heisst immer, dass die ganze TAbelle in den
Hauptspeicher geladen werden muss, was natürlich bei langsamen Netzwerken
verheerend sein kann.

Gruss
Henry
--
Microsoft MVP Office Access
Keine E-Mails auf Postings in NGs. Danke.
Access FAQ www.donkarl.com
Thomas Raasch
2008-12-10 10:42:15 UTC
Permalink
Hi,
Post by Josef Poetzl
[OT]
gestern kannte Thomas den Jet-Showplan noch nicht und heute spricht er
ihn schon abgekürzt mi "JSP" an. :-))
[/OT]
ich lerne schnell :)
Thomas Raasch
2008-12-10 10:49:01 UTC
Permalink
Hi,
Post by Henry Habermacher
Und hast Du anschliessend die Datenbank komprimiert, damit die Statistiken
aktualisiert werden? Falls nicht, mach' das und versuche es erneut.
Wenn das nichts nützt, dann lösche obigen Index wieder und lege einen über
aufAnzahl und einen über aufAnzahlGeliefert an, also zwei Indices,
komprimiere die Datenbank und versuche es erneut.
ja DB immer komprimiert
habe alles versucht
1x gemeinsamer Index
1x beide Felder getrennt indiziert
und zum Schluss hab ich sogar beides kombiniert - also beide Felder separat
indiziert und den DualIndex
Hört sich blödsinnig an... war es auch

Alles ist leider immer im Table Scan geendet
Post by Henry Habermacher
1. ein neues Feld AnzDiff hinzufügen
UPDATE tblAuftraege SET AnzDiff = aufAnzahl - aufAnzahlGeliefert
3. Index über AnzDiff anlegen
4. WHERE Bedingung so machen: "AnzDiff > 0"
werds wohl umstellen so, jo


Danke bisher!
Thomas
Thomas Raasch
2008-12-10 11:14:04 UTC
Permalink
Hallo,

brauche noch nen Tipp..

ich habe viele Filter die auf einen Status greifen. So gibt es bspw. das
Feld "aufStatus". Typ = Text(1)
Inhalt dieses Feldes kann sein:

vbNullString
D
E
P

indiziert ist es natürlich



Wenn die Bedingung:
"WHERE aufStatus = 'D'"
lautet, macht er nen "rushmore" und alles ist wunderbar

Wenn die Bedingung aber:
"WHERE aufStatus <> 'D'"
lautet, macht er nen TableScan. Und wie sollte es anders sein... ich brauch
diesen NOT-Vergleich


Hab ich mich also belesen und es stand geschrieben, man solle nicht "NOT
aufStatus = 'D'" nehmen sondern eben "<>". Also so wie ich es sowieso schon
mache...


Guck ich mir nun den Showplan an dann steht dort:

01) Restrict rows of table tblAngebote
by scanning
testing expression "Not angStatus='D'"


Jet (oder Access) wandelt mein "<>" also in ein "NOT =" um.
Und wie dort steht macht er nen TableScan und kein rush :(


Gibt es hierzu Hinweise?

Grüße
Thomas
Henry Habermacher
2008-12-10 11:29:04 UTC
Permalink
Hallo Thomas
Post by Thomas Raasch
vbNullString
D
E
P
indiziert ist es natürlich
"WHERE aufStatus = 'D'"
lautet, macht er nen "rushmore" und alles ist wunderbar
"WHERE aufStatus <> 'D'"
lautet, macht er nen TableScan. Und wie sollte es anders sein... ich
brauch diesen NOT-Vergleich
Versuch' mal: WHERE aufstatus IN('', E, P)

(orausgesetzt, Du meinst mit vbNullString, das was VB darunter versteht,
also ein '' und nicht ein Null in der DB.

Gruss
Henry
--
Microsoft MVP Office Access
Keine E-Mails auf Postings in NGs. Danke.
Access FAQ www.donkarl.com
Jens Schilling
2008-12-10 11:41:58 UTC
Permalink
Hallo, Henry
Post by Henry Habermacher
Post by Thomas Raasch
"WHERE aufStatus = 'D'"
lautet, macht er nen "rushmore" und alles ist wunderbar
"WHERE aufStatus <> 'D'"
lautet, macht er nen TableScan. Und wie sollte es anders sein... ich
brauch diesen NOT-Vergleich
Versuch' mal: WHERE aufstatus IN('', E, P)
Das mag eine Lösung sein, ich aber frage mich, ob hier nicht auch ein
Normalisierungsproblem vorliegt ....

Tschüs
Jens
Thomas Raasch
2008-12-10 11:51:18 UTC
Permalink
Hi
Post by Henry Habermacher
Versuch' mal: WHERE aufstatus IN('', E, P)
fast gut!
das nimmt schonmal den Index (rushmore) aber es fallen die DS mit leerem
Status raus...
habe das erweitert auf
WHERE aufstatus IN('', E, P, NULL)

aber auch hier fallen die mit leerem Status raus?!

mache ich
NZ(aufStatus, 'E') = 'E'
dann kommen alle


hmmm
wie auch immer, die Lösung von Josef geht und erledigt genau das gewünschte


Grüße
Henry Habermacher
2008-12-10 12:07:57 UTC
Permalink
Hallo Thomas
Post by Thomas Raasch
Post by Henry Habermacher
Versuch' mal: WHERE aufstatus IN('', E, P)
Sollte wohl IN('', 'E', 'P') heissen
Post by Thomas Raasch
das nimmt schonmal den Index (rushmore) aber es fallen die DS mit leerem
Status raus...
habe das erweitert auf
WHERE aufstatus IN('', E, P, NULL)
Nein, das geht nicht. Du kannst nicht auf IN(NULL) prüfen, wenn schon, dann

WHERE aufStatus IN('', 'E', 'P') OR aufStatus IS NULL
Post by Thomas Raasch
mache ich
NZ(aufStatus, 'E') = 'E'
dann kommen alle
Ob da allerdings Rushmore noch benutzt wird, bezweifle ich.

Gruss
Henry
--
Microsoft MVP Office Access
Keine E-Mails auf Postings in NGs. Danke.
Access FAQ www.donkarl.com
Josef Poetzl
2008-12-10 11:39:18 UTC
Permalink
Hallo!

Thomas Raasch schrieb:
[...]
Post by Thomas Raasch
"WHERE aufStatus <> 'D'"
lautet, macht er nen TableScan. Und wie sollte es anders sein... ich brauch
diesen NOT-Vergleich
Hab ich mich also belesen und es stand geschrieben, man solle nicht "NOT
aufStatus = 'D'" nehmen sondern eben "<>". Also so wie ich es sowieso schon
mache...
01) Restrict rows of table tblAngebote
by scanning
testing expression "Not angStatus='D'"
Jet (oder Access) wandelt mein "<>" also in ein "NOT =" um.
Und wie dort steht macht er nen TableScan und kein rush :(
Dem Jet-Abfrageoptimierer muss man öfter ein wenig helfen. Der ist
nicht unbedingt sehr schlau. :-)

Mit
... WHERE aufStatus < 'D' OR aufStatus > 'D'
sollte in Index verwendet werden.
(eventuell noch "OR aufStatus IS NULL" anhängen)

mfg
Josef
--
EPT: (Access Error Prevention Table) http://access.joposol.com/
FAQ: (Access-FAQ von Karl Donaubauer) http://www.donkarl.com/
Thomas Raasch
2008-12-10 11:52:17 UTC
Permalink
Post by Josef Poetzl
Dem Jet-Abfrageoptimierer muss man öfter ein wenig helfen. Der ist
nicht unbedingt sehr schlau. :-)
Mit
... WHERE aufStatus < 'D' OR aufStatus > 'D'
sollte in Index verwendet werden.
(eventuell noch "OR aufStatus IS NULL" anhängen)
das wars... "aufStatus IS NULL"
das geht
perfekt




Vielen Dank
Thomas
Henry Habermacher
2008-12-10 12:09:28 UTC
Permalink
Hallo Thomas
Post by Thomas Raasch
das wars... "aufStatus IS NULL"
das geht
perfekt
Und wie lange geht's jetzt, das Formular zu laden?

Im übrigen: Es wäre vielleicht sinnvoll, einen Mehrfeld Index über
(aufStatus, aufAnzahl) zu legen, statt der beiden einzelnen Indices, falls
Du immer mit beiden Feldern suchen gehst.

Gruss
Henry
--
Microsoft MVP Office Access
Keine E-Mails auf Postings in NGs. Danke.
Access FAQ www.donkarl.com
Thomas Raasch
2008-12-10 13:44:00 UTC
Permalink
Hi,
Post by Henry Habermacher
Und wie lange geht's jetzt, das Formular zu laden?
2-3 Sek.
also mehr als gut
Post by Henry Habermacher
Im übrigen: Es wäre vielleicht sinnvoll, einen Mehrfeld Index über
(aufStatus, aufAnzahl) zu legen, statt der beiden einzelnen Indices, falls
Du immer mit beiden Feldern suchen gehst.
ja also entweder wird nach Status gefiltert oder nach Anzahl
beides gleichzeitig kommt idR. nie vor


Grüße
Thomas
Sascha Trowitzsch
2008-12-10 12:54:21 UTC
Permalink
Hi,
Post by Thomas Raasch
Post by Josef Poetzl
Dem Jet-Abfrageoptimierer muss man öfter ein wenig helfen. Der ist
nicht unbedingt sehr schlau. :-)
Mit
... WHERE aufStatus < 'D' OR aufStatus > 'D'
sollte in Index verwendet werden.
(eventuell noch "OR aufStatus IS NULL" anhängen)
das wars... "aufStatus IS NULL"
das geht
perfekt
Ja, ich gehe auch immer mehr dazu über, JET den Plan quasi vorzugeben, statt
mich auf den Optimizer zu verlassen.
Das führt dann, allgemein asugedrückt, zu auseinandergenommenen Kriterien mit
vielen mehrfach kombinierten ANDs und ORs in Klammern.
Interessanterweise ist das dann eine Syntax, wie sie etwa ADO-Recordset-Filter
verlangen. Sowas wie hier (Remarks) erläutert:
http://msdn.microsoft.com/en-us/library/ms676691(VS.85).aspx

Ciao, Sascha
Karl Donaubauer
2008-12-10 18:25:07 UTC
Permalink
...
.> Hab ich mich also belesen und es stand geschrieben, man solle nicht
"NOT aufStatus = 'D'" nehmen sondern eben "<>". Also so wie ich es
sowieso schon mache...
.>
01) Restrict rows of table tblAngebote
by scanning
testing expression "Not angStatus='D'"
Jet (oder Access) wandelt mein "<>" also in ein "NOT =" um.
Und wie dort steht macht er nen TableScan und kein rush :(
Gibt es hierzu Hinweise?
Die Lösung hast du eh schon. Ich weiß nicht, was du mit "belesen" meinst,
aber in dem von mir in dieser Diskussion bereits genannten MZ-Skript von
der AEK8 wird die Thematik der performanteren Auflösung von Not und <>
mehrfach ab Seite 33 behandelt.
--
HTH
Karl
********* Ich beantworte keine Access-Fragen per Email. *********
Access-FAQ: http://www.donkarl.com
Jens Schilling
2008-12-10 19:24:41 UTC
Permalink
Hallo, Karl
Post by Karl Donaubauer
Post by Thomas Raasch
Jet (oder Access) wandelt mein "<>" also in ein "NOT =" um.
Die Lösung hast du eh schon. Ich weiß nicht, was du mit "belesen"
meinst, aber in dem von mir in dieser Diskussion bereits genannten
MZ-Skript von der AEK8 wird die Thematik der performanteren Auflösung
von Not und <> mehrfach ab Seite 33 behandelt.
Joo; dort ist nachzulesen, was ich in meiner Antwort auf Henrys Vorschlag
ebenfalls angedeutet habe: ein Normalisierungsproblem .

Tschüs
Jens
Thomas Raasch
2008-12-12 08:36:09 UTC
Permalink
Hi,
Post by Jens Schilling
Joo; dort ist nachzulesen, was ich in meiner Antwort auf Henrys Vorschlag
ebenfalls angedeutet habe: ein Normalisierungsproblem .
ööhhmmm wo soll denn hier das Normalisierungsproblem sein?
pro DS wird der Status geführt - ein Text-Feld der Größe 1

Ich könnte die 5 möglichen Buchstaben auslagern in eine andere Tabelle und
dann nur den Schlüssel speichern aber wäre das nicht etwas übertrieben?!?
Und eine Problemlösung wäre das ja auch nicht. Meine Abfrage bräuchte dann
nur einen JOIN mehr und die WHERE wäre quasi identisch.


Grüße
Thomas
Jens Schilling
2008-12-12 09:01:47 UTC
Permalink
Hallo, Thomas
Post by Thomas Raasch
ööhhmmm wo soll denn hier das Normalisierungsproblem sein?
pro DS wird der Status geführt - ein Text-Feld der Größe 1
Ich könnte die 5 möglichen Buchstaben auslagern in eine andere
Tabelle und dann nur den Schlüssel speichern aber wäre das nicht
etwas übertrieben?!?
Nein, es wäre normalisiert ;-)

Kannst Du mit an Sicherheit grenzender Wahrscheinlichkeit ausschliessen,
dass Du niemals weitere Status brauchen wirst ?

Und eine Problemlösung wäre das ja auch nicht.
Post by Thomas Raasch
Meine Abfrage bräuchte dann nur einen JOIN mehr und die WHERE wäre
quasi identisch.
Ja, einen Join mehr - aber Du hättest auch einen Index mehr (der PK der
Tabelle); und - je nach Datenmenge vielleicht auch nur theoretisch - nach
einem Zahlenwert ist schneller gesucht als nach einem String.
--
Gruss
Jens
______________________________
FAQ: http://www.donkarl.com
Peter Doering
2008-12-12 09:28:06 UTC
Permalink
Hallo Jens,
Post by Thomas Raasch
ööhhmmm wo soll denn hier das Normalisierungsproblem sein?
pro DS wird der Status geführt - ein Text-Feld der Größe 1
[...]
Karl bezog sich uebrigens nicht auf das Normalisierungsscript sondern auf
das zu Performance in Abfragen. ;-)

Gruss - Peter
--
Mitglied im http://www.dbdev.org
FAQ: http://www.donkarl.com
Jens Schilling
2008-12-12 12:59:33 UTC
Permalink
Hallo, Peter
Post by Peter Doering
Post by Thomas Raasch
ööhhmmm wo soll denn hier das Normalisierungsproblem sein?
pro DS wird der Status geführt - ein Text-Feld der Größe 1
[...]
Karl bezog sich uebrigens nicht auf das Normalisierungsscript sondern
auf das zu Performance in Abfragen. ;-)
Hmm - ich habe geöffnet das Dokument "MZPerformance", lese die Seite 33 und
finde das Folgende:

[...]
Problematisch sind:
- <>
[...]

Wenn solche Filterungen nach hintenliegenden Feldinhalten systematisch
auftauchen, ist die DB falsch normalisiert [...]
----

;-)
--
Gruss
Jens
______________________________
FAQ: http://www.donkarl.com
Peter Doering
2008-12-12 14:34:28 UTC
Permalink
Hallo Jens,
Post by Jens Schilling
Post by Peter Doering
Post by Thomas Raasch
ööhhmmm wo soll denn hier das Normalisierungsproblem sein?
pro DS wird der Status geführt - ein Text-Feld der Größe 1
[...]
Karl bezog sich uebrigens nicht auf das Normalisierungsscript sondern
auf das zu Performance in Abfragen. ;-)
Hmm - ich habe geöffnet das Dokument "MZPerformance", lese die Seite 33 und
[...]
- <>
[...]
Wenn solche Filterungen nach hintenliegenden Feldinhalten systematisch
auftauchen, ist die DB falsch normalisiert [...]
----
Und ich dachte schon, du waerst in der FAQ bei den MZ-Vortraegen in der
Zeile verrutscht ;-)

Gruss - Peter
--
Mitglied im http://www.dbdev.org
FAQ: http://www.donkarl.com
Jens Schilling
2008-12-12 23:24:01 UTC
Permalink
Hallo, Peter
Post by Peter Doering
Und ich dachte schon, du waerst in der FAQ bei den MZ-Vortraegen in
der Zeile verrutscht ;-)
Niemals ...

Die MZ'schen Vorträge und Referate kenne ich auswendig, kann diese im Schlaf
herunterbeten, und befolge und beachte deren Empfehlungen und Ratschläge bis
ins kleinste Detail ;-)

Getreu dem Motto: "Du sollst keinen anderen MZ neben Codd haben"

Gute Nacht
Jens
Thomas Raasch
2008-12-12 09:35:39 UTC
Permalink
Hi,
Post by Jens Schilling
Post by Thomas Raasch
ööhhmmm wo soll denn hier das Normalisierungsproblem sein?
pro DS wird der Status geführt - ein Text-Feld der Größe 1
Ich könnte die 5 möglichen Buchstaben auslagern in eine andere
Tabelle und dann nur den Schlüssel speichern aber wäre das nicht
etwas übertrieben?!?
Nein, es wäre normalisiert ;-)
verstehe... :)
aber das ist doch rein praktisch etwas übertrieben oder?!?
man grenzt ja auch in der Kunden-Tabelle den Ort nicht aus - und das würde
ich noch eher verstehen. In Verbindung mit der PLZ dann sowieso - und auch
das wird in der Praxis doch eher nicht gemacht. (abgesehen vom Problem Ort
==> PLZ aber PLZ !==> Ort)
Post by Jens Schilling
Kannst Du mit an Sicherheit grenzender Wahrscheinlichkeit ausschliessen,
dass Du niemals weitere Status brauchen wirst ?
janee (c)Atze Schröder
also eigentlich kommt kein Status mehr dazu
aber selbst wenn wäre es auch egal ob ich nun 5 Buchstaben hätte oder 6!?
Oder 10.
In jedem Fall wird das Feld Text(1) bleiben
Post by Jens Schilling
Ja, einen Join mehr - aber Du hättest auch einen Index mehr (der PK der
Tabelle); und - je nach Datenmenge vielleicht auch nur theoretisch - nach
einem Zahlenwert ist schneller gesucht als nach einem String.
nunja, nach Zahlen sucht es sich schneller - jo
Aber was benötigt der JOIN an Zeit? Ob man da wirklich was rausholt?!



Grüße
Schönes WE
ich mach Feierabend :)
Josef Poetzl
2008-12-12 10:13:18 UTC
Permalink
Hallo!
Post by Thomas Raasch
Post by Jens Schilling
Post by Thomas Raasch
ööhhmmm wo soll denn hier das Normalisierungsproblem sein?
pro DS wird der Status geführt - ein Text-Feld der Größe 1
Ich könnte die 5 möglichen Buchstaben auslagern in eine andere
Tabelle und dann nur den Schlüssel speichern aber wäre das nicht
etwas übertrieben?!?
Nein, es wäre normalisiert ;-)
verstehe... :)
aber das ist doch rein praktisch etwas übertrieben oder?!?
Ein Beispiel:

tabAngebotStatus
- angStatus (varchar(1), PK)


select
...
from
tblAngebote A
inner join
tabAngebotStatus S
ON S.angStatus = A.angStatus
WHERE
S.angStatus <> 'D'

=>
Jetzt läuft zwar wieder ein table scan, aber nur noch auf die
Status-Tabelle mit wenigen DS. Wenn dann des Statusfeld in der
Angebotstabelle indiziert ist, sollte darauf ein Index-Seek laufen.
Anm.: Ich prüfte das nicht im Jet-Showplan, hoffe aber, dass ich das
Verhalten richtig beschrieb. ;-)


noch netter wäre es so:
tabAngebotStatus
- angStatus (PK)
- StatusHatEigenschaftD (ja/nein)
(.. natürlich besser lesbaren Namen verwenden)

select
...
from
tblAngebote A
inner join
tabAngebotStatus S
ON S.angStatus = A.angStatus
WHERE
S.StatusHatEigenschaftD = 0


mfg
Josef
--
EPT: (Access Error Prevention Table) http://access.joposol.com/
FAQ: (Access-FAQ von Karl Donaubauer) http://www.donkarl.com/
Sascha Trowitzsch
2008-12-12 11:48:16 UTC
Permalink
Hi,
Post by Josef Poetzl
Hallo!
Post by Thomas Raasch
Post by Jens Schilling
Post by Thomas Raasch
ööhhmmm wo soll denn hier das Normalisierungsproblem sein?
pro DS wird der Status geführt - ein Text-Feld der Größe 1
Ich könnte die 5 möglichen Buchstaben auslagern in eine andere
Tabelle und dann nur den Schlüssel speichern aber wäre das nicht
etwas übertrieben?!?
Nein, es wäre normalisiert ;-)
verstehe... :)
aber das ist doch rein praktisch etwas übertrieben oder?!?
tabAngebotStatus
- angStatus (varchar(1), PK)
select
...
from
tblAngebote A
inner join
tabAngebotStatus S
ON S.angStatus = A.angStatus
WHERE
S.angStatus <> 'D'
=>
Jetzt läuft zwar wieder ein table scan, aber nur noch auf die
Status-Tabelle mit wenigen DS. Wenn dann des Statusfeld in der
Angebotstabelle indiziert ist, sollte darauf ein Index-Seek laufen.
Anm.: Ich prüfte das nicht im Jet-Showplan, hoffe aber, dass ich das
Verhalten richtig beschrieb. ;-)
tabAngebotStatus
- angStatus (PK)
- StatusHatEigenschaftD (ja/nein)
(.. natürlich besser lesbaren Namen verwenden)
select
...
from
tblAngebote A
inner join
tabAngebotStatus S
ON S.angStatus = A.angStatus
WHERE
S.StatusHatEigenschaftD = 0
Prinzipell finde ich es richtig, sich diese Vorgänge zu verdeutlichen und zu
diskutieren, weil viel zu wenig auf die Arbeitsweise der JET-Engine geachtet
wird und mangelhafte Performance immer wieder gerne auf irgendwelche
Anbindungsprobleme zum Server oder gar Unvermögen von Microsoft geschoben wird.
Fast immer handelt es sich um unzureichende Indizierung oder schlechte
Abfragenkonstrukte, wenn es an der Performance mangelt.
Nur ist das mit der reinen Lehre so eine Sache...
Also ich vor ein paar Tagen den Showplan Capturer bearbeitete, habe ich nebenbei
einige der in diesem erwähnten Thread Not-Null-Lösungen durchgetestet und auf
verschiedene Tabellen Abfragen laufen lassen und die Performance gemessen. Damit
es halbwegs realitätsnah abgeht, lag das Backend auf einem lahmen Netzlaufwerk
und die Tabellen hatten zwischen 10- und 200TSD Datensätze.
Das Ergebnis: Es war völlig unerheblich, ob ein Tablescan über NOT-Null auf ein
indiziertes Feld ablief, oder ob der Index per >'..' genutzt wurde. Beides war
etwa gleich schnell. Erstaunlicherweise hatte dabei die Größe der Tabelle nur
eine marginale Auswirkung auf die Ergebnisse. (Ich ging davon aus, dass mit
wachsender Zahl von DS die Nutzung des Index sich stärker auswirken sollte.)

Das deckt sich mit unzähligen Performancetests, die ich die letzten Jahren so
durchführte. Es ist fast unmöglich vorauszusagen, welche Lösung bei Filebackends
die bessere ist, weil sehr viele Faktoren mitspielen:
- Der Queryplan; die Gestalt der Tabelle(n); die Netzwerkanbindung; die
Geschwindigkeit des Servers beim Locking; Einstellungen der JET-Engine; die
Datenzugriffsmethode; das Caching (...welches bei Performancemessungen IMHO die
größte Unbekannte darstellt); und die Vorsortierung und die Daten selbst sind
ebenfalls wichtig.
Und *wie* JET B-Trees speichert, auswertet, wie der Index gerade genau in
Speicherseiten verteilt ist, darüber kann man eh nur spekulieren.
Soll heißen: Probieren geht über studieren. Mit vorschnellen Empfehlungen muss
man vorsichtig sein.
Und das schließt für mich ein, dass ein Tablescan offensichtlich nicht per se
pfui sein muss. Es haut einfach nicht hin, dass "using Index..." oder
...rushmore *automatisch* soviel flotter vonstatten geht, als ein Scan.

Ciao, Sascha
Josef Poetzl
2008-12-12 12:13:33 UTC
Permalink
Hallo!

Sascha Trowitzsch schrieb:
[...]
Post by Sascha Trowitzsch
Das Ergebnis: Es war völlig unerheblich, ob ein Tablescan über NOT-Null auf ein
indiziertes Feld ablief, oder ob der Index per >'..' genutzt wurde.
Wieviel Prozent der Gesamtmenge wurde durch den Vergleich
ausgeschlossen?
Wenne snur wenige DS sind, könnte ich mir sogar vorstellen, dass ein
Table scan schneller ist, das kein Bookmark-lookup mehr erforderlich
wird.


[...]
Post by Sascha Trowitzsch
Und das schließt für mich ein, dass ein Tablescan offensichtlich nicht per se
pfui sein muss.
Problem bei Jet: man sieht im Showplan nicht wirklich, was im
Hintergrund abläuft. Im SQL-Server-Ausführungsplan ist das um einiges
genauer aufgelistet. Man kann aber nicht vom SQL-Server-Ablaufplan auf
die Jet-Ausfürhung zurückschließen.
Post by Sascha Trowitzsch
Es haut einfach nicht hin, dass "using Index..." oder
...rushmore *automatisch* soviel flotter vonstatten geht, als ein Scan.
hättest du eine Beispiel-mdb?
Mir fällt nämlich kein Beispiel ein, bei dem ein Index-*Seek* (nicht
Index-scan!) nicht schneller als ein Table-Scan ist. ... außer wie
oben erwähnt, bei "Feld <> wert", wenn die auszuschließende Datenmenge
gering ist.

aber ein
select feld1, feld2 from tabelle where feldX = 'A'
auf eine Tabelle mit einigen tausend DS wird imo ein Index-Seek immer
schneller sein als ein Table scan.


Übrigens:
die neue DAO für Ac07 ist bezüglich Index-Verwendung etwas schlauer
geworden. Es werden unter bestimmten Bedingungen sogar zwei
Ein-Felder-Indizes kombiniert. (In diesem Fall wird dann auch ein
"Feld <> Wert" in eine Index-Verwendung ausgelöst.)


mfg
Josef
--
EPT: (Access Error Prevention Table) http://access.joposol.com/
FAQ: (Access-FAQ von Karl Donaubauer) http://www.donkarl.com/
Sascha Trowitzsch
2008-12-12 12:41:04 UTC
Permalink
Hi,
Post by Josef Poetzl
Hallo!
[...]
Post by Sascha Trowitzsch
Das Ergebnis: Es war völlig unerheblich, ob ein Tablescan über NOT-Null auf ein
indiziertes Feld ablief, oder ob der Index per >'..' genutzt wurde.
Wieviel Prozent der Gesamtmenge wurde durch den Vergleich
ausgeschlossen?
Wenne snur wenige DS sind, könnte ich mir sogar vorstellen, dass ein
Table scan schneller ist, das kein Bookmark-lookup mehr erforderlich
wird.
Ca. 30% der Felder waren NULL. (!Vorname)
Es handelte sich um eine originale Stammdaten-Tabelle eines Kunden.
Post by Josef Poetzl
[...]
Post by Sascha Trowitzsch
Und das schließt für mich ein, dass ein Tablescan offensichtlich nicht per se
pfui sein muss.
Problem bei Jet: man sieht im Showplan nicht wirklich, was im
Hintergrund abläuft. Im SQL-Server-Ausführungsplan ist das um einiges
genauer aufgelistet. Man kann aber nicht vom SQL-Server-Ablaufplan auf
die Jet-Ausfürhung zurückschließen.
Das scheint mir der Punkt zu sein. *Was* heißt im Showplan denn "scans table"?
Ich habe den Traffic leider nicht gemonitored, aber mir scheint, dass dazu nicht
unbedingt die ganze Tabelle geholt wird? Oder sie war halt nach dem ersten Holen
nunmal im Cache, was die Analyse erschwert - obwohl das der Realität im Alltag
dann ja durchaus entspricht.
Post by Josef Poetzl
Post by Sascha Trowitzsch
Es haut einfach nicht hin, dass "using Index..." oder
...rushmore *automatisch* soviel flotter vonstatten geht, als ein Scan.
hättest du eine Beispiel-mdb?
Mir fällt nämlich kein Beispiel ein, bei dem ein Index-*Seek* (nicht
Index-scan!) nicht schneller als ein Table-Scan ist. ... außer wie
oben erwähnt, bei "Feld <> wert", wenn die auszuschließende Datenmenge
gering ist.
BeispielDB kann ich nicht bieten, weil ich solche Tests immer in bestehende
ältere DBs mit wüstem Moduldurcheinander einbaue. ;-)
Das - Index-Seek, Aussschlusskriterium, etc. - bezweifle ich ja keinesfalls!
Ich sage nur, dass das gemessene Beispiel nicht diesen Erwartungen entsprach.
Und dass man eigentlich nur spekulieren kann, an was es liegt.
Post by Josef Poetzl
aber ein
select feld1, feld2 from tabelle where feldX = 'A'
auf eine Tabelle mit einigen tausend DS wird imo ein Index-Seek immer
schneller sein als ein Table scan.
die neue DAO für Ac07 ist bezüglich Index-Verwendung etwas schlauer
geworden. Es werden unter bestimmten Bedingungen sogar zwei
Ein-Felder-Indizes kombiniert. (In diesem Fall wird dann auch ein
"Feld <> Wert" in eine Index-Verwendung ausgelöst.)
Ich habe das (den entspr. Forumsthread und die PN) trotz ungemütlicher
Arbeitsauslastung sehr wohl registriert. ;-)

Gruß, Sascha
Josef Poetzl
2008-12-12 14:16:42 UTC
Permalink
Hallo!
Post by Sascha Trowitzsch
Post by Josef Poetzl
Wieviel Prozent der Gesamtmenge wurde durch den Vergleich
ausgeschlossen?
Wenn es nur wenige DS sind, könnte ich mir sogar vorstellen, dass ein
Table scan schneller ist, da kein Bookmark-lookup mehr erforderlich
wird.
Ca. 30% der Felder waren NULL. (!Vorname)
hm .. in diesem Fall kann ich das mit einem Test unter AcXP nicht
bestätigen.

| S(1).StartT
| Set rst = db.OpenRecordset("select * from tTestdaten where Text2 > ''")
| rst.MoveLast
| rst.Close
| S(1).StopT
|
| S(2).StartT
| Set rst = db.OpenRecordset("select * from tTestdaten where Text2 IS NOT NULL")
| rst.MoveLast
| rst.Close
| S(2).StopT

=>
S(1).Time ... < 500 ms
S(2).Time ... > 4000 ms
bei einer Datenbasis von 2 Mio Ds, davon 500k ohne Wert

Anm.: ohne Move-Last bzw. "Order By" wäre der Vergleich nicht
aussagekräftig.
Gemein wird "Select ... where Text2 ... Order by Text2" ohne
rst.MoveLast, dann kann sich "where Text2 is not null" verstecken.
:-))
S(1).Time ... 3 ms
S(2).Time ... > 12000 ms

Die Zeiten ermittelte ich unter AcXP, mit einem verknüpften BE, das in
einem lokalem Verzeichnis lag.
Post by Sascha Trowitzsch
Post by Josef Poetzl
die neue DAO für Ac07 ist bezüglich Index-Verwendung etwas schlauer
geworden. Es werden unter bestimmten Bedingungen sogar zwei
Ein-Felder-Indizes kombiniert. (In diesem Fall wird dann auch ein
"Feld <> Wert" in eine Index-Verwendung ausgelöst.)
Ich habe das (den entspr. Forumsthread und die PN) trotz ungemütlicher
Arbeitsauslastung sehr wohl registriert. ;-)
Dieser "Übrigens" war nicht nur für dich gedacht. :-))

mfg
Josef
--
EPT: (Access Error Prevention Table) http://access.joposol.com/
FAQ: (Access-FAQ von Karl Donaubauer) http://www.donkarl.com/
Henry Habermacher
2008-12-12 10:15:16 UTC
Permalink
Hallo Jens
Post by Jens Schilling
Post by Thomas Raasch
ööhhmmm wo soll denn hier das Normalisierungsproblem sein?
pro DS wird der Status geführt - ein Text-Feld der Größe 1
Ich könnte die 5 möglichen Buchstaben auslagern in eine andere
Tabelle und dann nur den Schlüssel speichern aber wäre das nicht
etwas übertrieben?!?
Nein, es wäre normalisiert ;-)
Aber Jens, das ist es auch so. Es gibt keine Normalisierungsregel, die
verhindert, dass selbssprechende Schlüssel verwendet werden dürfen. Das
einzige was man hier bemängeln könnte, wäre, dass hier mit der RI nicht
sichergestellt wird, dass nicht falsche Werte eingetragen werden, hat aber
grundsätzlich mit der Normalisierung nichts zu tun.
Post by Jens Schilling
Kannst Du mit an Sicherheit grenzender Wahrscheinlichkeit ausschliessen,
dass Du niemals weitere Status brauchen wirst ?
Auch das ist kein Problem, einfach einen anderen Schlüssel vergeben.
Post by Jens Schilling
Und eine Problemlösung wäre das ja auch nicht.
Post by Thomas Raasch
Meine Abfrage bräuchte dann nur einen JOIN mehr und die WHERE wäre
quasi identisch.
Ja, einen Join mehr - aber Du hättest auch einen Index mehr (der PK der
Tabelle); und - je nach Datenmenge vielleicht auch nur theoretisch - nach
einem Zahlenwert ist schneller gesucht als nach einem String.
1 Byte (Text(1)) oder 2 Byte (Long), ich glaube es ist schneller, nicht zu
joinen.

Gruss
Henry
--
Microsoft MVP Office Access
Keine E-Mails auf Postings in NGs. Danke.
Access FAQ www.donkarl.com
Thomas Winkler
2008-12-12 10:46:08 UTC
Permalink
Hi,
Post by Henry Habermacher
1 Byte (Text(1)) oder 2 Byte (Long), ich glaube es ist schneller, nicht
zu joinen.
War es nicht so, dass ein 32 Bit breit angebundener Prozessor *immer* 32
Bit pro Zyklus bekommt? Demnach wäre es bei weniger als 4 Byte egal, wie
lang die zu vergleichenden Werte sind.

Erst bei mehr als 4 Byte langen Vergleichen sollte sich die Überlegung
Text oder Long wirklich bezahlt machen, da damit ggf ein oder mehrere
Prozessorzyklen gespart werden könnten.

Ein 4-Byte-Long-Vergleich würde also ggü. einem 5-Byte-Text-Vergleich
theoretisch um 50 % schneller ablaufen.

HTH

Thomas

--
"Access? Damit arbeite ich nicht. Das ist doch nur ein abgespecktes Excel."
Stefan Hoffmann
2008-12-12 14:37:36 UTC
Permalink
hallo Thomas,
Post by Thomas Winkler
War es nicht so, dass ein 32 Bit breit angebundener Prozessor *immer* 32
Bit pro Zyklus bekommt? Demnach wäre es bei weniger als 4 Byte egal, wie
lang die zu vergleichenden Werte sind.
Jain.
Post by Thomas Winkler
Ein 4-Byte-Long-Vergleich würde also ggü. einem 5-Byte-Text-Vergleich
theoretisch um 50 % schneller ablaufen.
Jain.

Das wichtigste Kriterium war und ist das Alignment der Werte im Speicher.


mfG
--> stefan <--
--
Access-FAQ http://www.donkarl.com/
KnowHow.mdb http://www.freeaccess.de
Newbie-Info http://www.doerbandt.de/Access/Newbie.htm
Thomas Winkler
2008-12-12 14:44:59 UTC
Permalink
Hi,
Post by Stefan Hoffmann
Post by Thomas Winkler
War es nicht so, dass ein 32 Bit breit angebundener Prozessor *immer*
32 Bit pro Zyklus bekommt? Demnach wäre es bei weniger als 4 Byte
egal, wie lang die zu vergleichenden Werte sind.
Jain.
Hmm. Vielleicht noch ein paar mehr Details?
Post by Stefan Hoffmann
Post by Thomas Winkler
Ein 4-Byte-Long-Vergleich würde also ggü. einem 5-Byte-Text-Vergleich
theoretisch um 50 % schneller ablaufen.
Jain.
Hmm. Vielleicht noch ein paar mehr Details?
Post by Stefan Hoffmann
Das wichtigste Kriterium war und ist das Alignment der Werte im Speicher.
Hmm. Vielleicht noch ein paar mehr Details?

Thomas

--
"Access? Damit arbeite ich nicht. Das ist doch nur ein abgespecktes Excel."
Stefan Hoffmann
2008-12-12 15:02:29 UTC
Permalink
hallo Thomas,
Post by Thomas Winkler
Post by Thomas Winkler
War es nicht so, dass ein 32 Bit breit angebundener Prozessor *immer*
32 Bit pro Zyklus bekommt? Demnach wäre es bei weniger als 4 Byte
egal, wie lang die zu vergleichenden Werte sind.
Jain.
Hmm. Vielleicht noch ein paar mehr Details?
http://en.wikipedia.org/wiki/Data_structure_alignment

Das Lesen von Werten aus dem RAM ist am schnellsten, wenn die Werte an
durch 4 ohne Rest teilbaren Speicheradressen stehen.


mfG
--> stefan <--
Henry Habermacher
2008-12-15 04:51:43 UTC
Permalink
Hallo Stefan
Post by Stefan Hoffmann
Das Lesen von Werten aus dem RAM ist am schnellsten, wenn die Werte an
durch 4 ohne Rest teilbaren Speicheradressen stehen.
Und was hat das mit der MDB zu tun? Diese liegt zum einen nicht im Speicher
und zum anderen werden da Pages gelesen.

Gruss
Henry
--
Microsoft MVP Office Access
Keine E-Mails auf Postings in NGs. Danke.
Access FAQ www.donkarl.com
Jetzt anmelden: NEK-1: http://www.donkarl.com/?nek
Sascha Trowitzsch
2008-12-15 11:37:50 UTC
Permalink
Hi,
Post by Henry Habermacher
Hallo Stefan
Post by Stefan Hoffmann
Das Lesen von Werten aus dem RAM ist am schnellsten, wenn die Werte an
durch 4 ohne Rest teilbaren Speicheradressen stehen.
Und was hat das mit der MDB zu tun? Diese liegt zum einen nicht im Speicher
und zum anderen werden da Pages gelesen.
..die aber unter Umständen dann doch im lokalen Cache liegen können. ;-)

Ciao, Sascha
Henry Habermacher
2008-12-15 11:46:08 UTC
Permalink
Hallo Sascha
Post by Sascha Trowitzsch
Post by Henry Habermacher
Und was hat das mit der MDB zu tun? Diese liegt zum einen nicht im
Speicher und zum anderen werden da Pages gelesen.
..die aber unter Umständen dann doch im lokalen Cache liegen können. ;-)
Ja und was willst Du damit sagen? Dass es dann schneller sei, einen Join
über eine Nummer mit einer Status Tabelle zu haben, als den 1 Zeichen langen
Status gleich in der Tabelle zu führen? Nicht eigentlich, oder?

Gruss
Henry
--
Microsoft MVP Office Access
Keine E-Mails auf Postings in NGs. Danke.
Access FAQ www.donkarl.com
Jetzt anmelden: NEK1: http://www.donkarl.com/?nek
Stefan Hoffmann
2008-12-15 11:52:25 UTC
Permalink
hallo Sascha,
Post by Sascha Trowitzsch
Post by Henry Habermacher
Post by Stefan Hoffmann
Das Lesen von Werten aus dem RAM ist am schnellsten, wenn die Werte an
durch 4 ohne Rest teilbaren Speicheradressen stehen.
Und was hat das mit der MDB zu tun? Diese liegt zum einen nicht im Speicher
und zum anderen werden da Pages gelesen.
..die aber unter Umständen dann doch im lokalen Cache liegen können. ;-)
Eben.

Und wenn es dann noch ein Textvergleich wird, dann wird es wieder
interessant, z.B. Knut-Morris-Pratt.


mfG
--> stefan <--
Stefan Hoffmann
2008-12-15 11:50:52 UTC
Permalink
hallo Henry,
Post by Henry Habermacher
Post by Stefan Hoffmann
Das Lesen von Werten aus dem RAM ist am schnellsten, wenn die Werte an
durch 4 ohne Rest teilbaren Speicheradressen stehen.
Und was hat das mit der MDB zu tun?
Nichts, daher hat er ja auch das OT vorangestellt.

Ich denke, ihm ging es wirklich um dir konkrete
Ausführungsgeschwindigkeit eines 32bit Prozessors.
Und da ist das Memory Alignment von Bedeutung, da es sonst zu
Straf-/Wartezyklen kommt, bis der eigentliche Wert verarbeitet werden kann.


mfG
--> stefan <--
Henry Habermacher
2008-12-15 12:04:25 UTC
Permalink
Hallo Stefan
Post by Stefan Hoffmann
Post by Henry Habermacher
Und was hat das mit der MDB zu tun?
Nichts, daher hat er ja auch das OT vorangestellt.
Ich sehe da [leicht OT] und was ich hier lese hat mit dem OP nichts mehr zu
tun, also [ganz OT] ;-)

Gruss
Henry
--
Microsoft MVP Office Access
Keine E-Mails auf Postings in NGs. Danke.
Access FAQ www.donkarl.com
Jetzt anmelden: NEK1: http://www.donkarl.com/?nek
Thomas Raasch
2008-12-12 08:23:54 UTC
Permalink
Hallo.
Post by Karl Donaubauer
Die Lösung hast du eh schon. Ich weiß nicht, was du mit "belesen" meinst,
aber in dem von mir in dieser Diskussion bereits genannten MZ-Skript von
der AEK8 wird die Thematik der performanteren Auflösung von Not und <>
mehrfach ab Seite 33 behandelt.
Upsi.. ja da stehts :)
und dort stehts sogar korrekt... das was ich gelesen hatte (wo war das
nur??) da stand, dass NOT zu einer Nicht-Nutzung des Indexes führt und aber
<> klappen soll....
Da irrt sich diese Quelle wohl.




Grüße
Thomas
Winfried Sonntag [MVP]
2008-12-09 09:58:56 UTC
Permalink
Post by Thomas Raasch
wir bauen Access-Progrämmchen für die Auftragsbearbeitung. Die Programme
sind bei manchen Kunden nun seit einigen Jahren im Einsatz. Das Format der
Access-Anwendung (FE) ist AccXP. Die reine Datenbank (BE) liegt ebenfalls
als AccXP vor. Die DB liegt idR. in einer Freigabe auf nem Windows-Server.
Es gibt viele Windows-Server. Betrifft es nur bestimmte
Versionen/Varianten? Ist ein SBS2003 dabei?
Post by Thomas Raasch
Das Netz ist zumeist nen 100MBit LAN.
Ansonsten ein GBit-LAN?
Post by Thomas Raasch
Es häufen sich nun leider die Beschwerden, dass die Anwendung immer
Ist das bei *allen* Kunden so, oder nur bei bestimmten? Betrifft das
alle Clients bei den jeweiligen Kunden, oder vielleicht nur bestimmte?
Post by Thomas Raasch
das Öffnen eines Formulars (Inhalt: Aufträge) dauert schonmal gerne 30s. Die
DB hat 150 MB und die angesprochene Tabelle hat ca. 60.000 Datensätze. Laut
System-Überwachungs-Tools holt sich Access bei Formularstart die komplette
Tabelle mit allen 60.000 Datensätzen, wertet danach lokal am Client den
FilterBy und OrderBy aus und zeigt das Ergebnis an.
Das Ordern und Filtern geht dabei in Sekundenschnelle - aber das Übertragen
der Tabelle durchs LAN dauert....
Wir haben auch ein Formular, direkt an die Tabelle gebunden, mit rund
24.000 DS, es wird auch beim aufrufen noch gerechnet und gem.
eingestellten Rechten aus- oder eingeblendet. Diese Form wird innerhalb
von 2 Sekunden angezeigt. Ich tippe eher auf ein Problem im Netz oder
auf dem dahinter stehenden Server.

Lass mal bei den Kunden das SMB-Signing kontrollieren und auf alle Fälle
gem. BestPraxis konfigurieren:
http://www.gruppenrichtlinien.de/HowTo/SMB_Signing.htm
Eine weitere Möglichkeit wäre auch noch das hier:
http://www.faq-o-matic.net/2008/03/14/gut-gedacht-schlecht-gemacht-hin-her-scalable-networking-pack/

Alternativ auch fragen, ob evtl. ein neuer Server oder ein neuer Switch
hinzugekommen ist.

Servus
Winfried
--
KnowHow.mdb: http://www.freeaccess.de/knowhow.asp
Access-FAQ: http://www.donkarl.com/AccessFAQ.htm
Access-Stammtisch: http://www.access-muenchen.de/
Richtig zitieren: http://einklich.net/usenet/zitier.htm
Thomas Raasch
2008-12-09 11:04:58 UTC
Permalink
Hi,
Post by Winfried Sonntag [MVP]
Es gibt viele Windows-Server. Betrifft es nur bestimmte
Versionen/Varianten? Ist ein SBS2003 dabei?
ja bisher (eher durch Zufall) liegt die DB bei den Kunden immer auf nem
SBS2003. Einer hat als "Server" nen WindowsXP :)
Post by Winfried Sonntag [MVP]
Post by Thomas Raasch
Das Netz ist zumeist nen 100MBit LAN.
Ansonsten ein GBit-LAN?
Jaaa das wäre eine Idee
Post by Winfried Sonntag [MVP]
Post by Thomas Raasch
Es häufen sich nun leider die Beschwerden, dass die Anwendung immer
Ist das bei *allen* Kunden so, oder nur bei bestimmten? Betrifft das
alle Clients bei den jeweiligen Kunden, oder vielleicht nur bestimmte?
Alle Kunden (die große DBs haben) auf allen Clients (Win2k, XP, Vista)
Post by Winfried Sonntag [MVP]
Wir haben auch ein Formular, direkt an die Tabelle gebunden, mit rund
24.000 DS, es wird auch beim aufrufen noch gerechnet und gem.
eingestellten Rechten aus- oder eingeblendet. Diese Form wird innerhalb
von 2 Sekunden angezeigt. Ich tippe eher auf ein Problem im Netz oder
auf dem dahinter stehenden Server.
Soso... wenn es nach 2 Sek angezeigt wird, steht dann untem in den
Datensatzschaltflächen (ich hoffe diese sind angezeigt) bereits "Datensatz 1
von 24.000" oder "Datensatz 1 von 100 (gefiltert)"
Weil erst wenn dieser Satz da steht ist die LAN-Übertragung fertig. Und das
ist mein Problem
Versuch mal, gleich zu Beginn, wenn dieser Satz noch nicht da steht auf
einen neuen DS zu springen (geht nicht).

Zum Testen eigent es sich wunderbar seine LAN-Karte auf "10MBit Half"
einzustellen. Dann kann man das Problem viel besser erkennen.




Grüße
Thomas
Winfried Sonntag [MVP]
2008-12-09 12:39:27 UTC
Permalink
Post by Thomas Raasch
Post by Winfried Sonntag [MVP]
Es gibt viele Windows-Server. Betrifft es nur bestimmte
Versionen/Varianten? Ist ein SBS2003 dabei?
ja bisher (eher durch Zufall) liegt die DB bei den Kunden immer auf nem
SBS2003. Einer hat als "Server" nen WindowsXP :)
Na wunderbar, damit kommen wir der Sache schon näher. Nimm das Backend
bei einem Kunden mal vom SBS runter und pack es auf einen Client. Jetzt
auf einem anderen Client im FE die Tabellen neu verknüpfen.
Geschwindigkeit testen. Welcher AV-Scanner ist in *genau* welcher
Version im Einsatz? Werden NW-Laufwerke gescannt? Werden *.MDBs
gescannt? Wenn zweimal ja, mal probehalber rausnehmen. Und bevor Du
jetzt sagst, Du hast den AV-Scanner schon deaktiviert, sag ich dir, Du
kannst ihn gar nicht deaktivieren. Nur mit einer *rückstandsfreien*
Deinstallation und anschließender Kontrolle, ob die Dienste auch weg
oder deaktiviert sind, kannst Du das vernünftig testen. Ein Deaktivieren
über das Symbol im Systray ist Augenwischerei, zumindest bei 99% der
AV-Scanner. Kontrollier doch mal nach dem deaktivieren, ob noch Prozesse
vom Scanner im Taskmanager aktiv sind. Am besten *vor* und *nach* dem
deaktivieren die Prozessliste anschauen.

Und ja, ein solches Problem hatten wir auch schon mit F-Secure, Abhilfe
war das ausschliessen von *.MDBs + *.LDBs beim scannen.
Post by Thomas Raasch
Post by Winfried Sonntag [MVP]
Post by Thomas Raasch
Das Netz ist zumeist nen 100MBit LAN.
Ansonsten ein GBit-LAN?
Jaaa das wäre eine Idee
Nö, das hilft nix wenn der Rest nicht auch passt, glaubs mir.
Post by Thomas Raasch
Post by Winfried Sonntag [MVP]
Post by Thomas Raasch
Es häufen sich nun leider die Beschwerden, dass die Anwendung immer
Ist das bei *allen* Kunden so, oder nur bei bestimmten? Betrifft das
alle Clients bei den jeweiligen Kunden, oder vielleicht nur bestimmte?
Alle Kunden (die große DBs haben) auf allen Clients (Win2k, XP, Vista)
Definiere große DBs. Wir haben hier ein FE auf den Clients und 4 BEs mit
insgesamt ~3 GB Volumen. Allerdings keinen SBS.
Post by Thomas Raasch
Post by Winfried Sonntag [MVP]
Wir haben auch ein Formular, direkt an die Tabelle gebunden, mit rund
24.000 DS, es wird auch beim aufrufen noch gerechnet und gem.
eingestellten Rechten aus- oder eingeblendet. Diese Form wird innerhalb
von 2 Sekunden angezeigt. Ich tippe eher auf ein Problem im Netz oder
auf dem dahinter stehenden Server.
Soso... wenn es nach 2 Sek angezeigt wird, steht dann untem in den
Datensatzschaltflächen (ich hoffe diese sind angezeigt) bereits "Datensatz 1
von 24.000" oder "Datensatz 1 von 100 (gefiltert)"
Natürlich steht da DS 1 von 24.000. Ich hab bei einem Bekannten ein FE
mit BE auf einem SBS im Einsatz, da gibts eine Tabelle Artikel mit
600.000 Datensätzen, auch bei diesem Formular ist die Anzahl 1 von
600.000 nach ca. 2 Sekunden da.
Post by Thomas Raasch
Weil erst wenn dieser Satz da steht ist die LAN-Übertragung fertig. Und das
ist mein Problem
Versuch mal, gleich zu Beginn, wenn dieser Satz noch nicht da steht auf
einen neuen DS zu springen (geht nicht).
Zum Testen eigent es sich wunderbar seine LAN-Karte auf "10MBit Half"
einzustellen. Dann kann man das Problem viel besser erkennen.
Warum sollte man das im Zeitalter von GBit-LAN machen?

Servus
Winfried
--
KnowHow.mdb: http://www.freeaccess.de/knowhow.asp
Access-FAQ: http://www.donkarl.com/AccessFAQ.htm
Access-Stammtisch: http://www.access-muenchen.de/
Richtig zitieren: http://einklich.net/usenet/zitier.htm
Sascha Trowitzsch
2008-12-09 15:15:07 UTC
Permalink
Hi,
Post by Winfried Sonntag [MVP]
Post by Thomas Raasch
Zum Testen eigent es sich wunderbar seine LAN-Karte auf "10MBit Half"
einzustellen. Dann kann man das Problem viel besser erkennen.
Warum sollte man das im Zeitalter von GBit-LAN machen?
...Mal abgesehen davon, dass es für solche Testzwecke Tools wie den Netlinter
(http://www.netlimiter.com/) gibt und man nicht gleich an Hardware-Einstellungen
rumschrauben muss.

Ciao, Sascha
Thomas Raasch
2008-12-09 15:54:00 UTC
Permalink
Post by Sascha Trowitzsch
Hi,
Post by Winfried Sonntag [MVP]
Post by Thomas Raasch
Zum Testen eigent es sich wunderbar seine LAN-Karte auf "10MBit Half"
einzustellen. Dann kann man das Problem viel besser erkennen.
Warum sollte man das im Zeitalter von GBit-LAN machen?
Warum?? Na ich zitiere mich mal selbst:
"Dann kann man das Problem viel besser erkennen."
Post by Sascha Trowitzsch
...Mal abgesehen davon, dass es für solche Testzwecke Tools wie den
Netlinter (http://www.netlimiter.com/) gibt und man nicht gleich an
Hardware-Einstellungen rumschrauben muss.
Wozu ein Tool installieren wenn Windows es selber in ausreichendem Umfang
kann?



Aber das führt weg vom Thema :)

Grüße
Thomas
Lesen Sie weiter auf narkive:
Loading...