Autor Beitrag
mandras
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 429
Erhaltene Danke: 107

Win 10
Delphi 6 Prof, Delphi 10.4 Prof
BeitragVerfasst: Sa 15.02.14 23:29 
Ein bestehendes Projekt soll bezüglich Performance verbessert werden, ohne auf ein Mal alles komplett umzukrempeln.

Aktuelles Problem hier nun:
In einem Formular wird eine Datenbanktabelle mittels DBGrid mit sehr vielen Spalten und so ca. 5000 Zeilen angezeigt.
Beim Öffnen des Formulars soll immer der vom Benutzer beim letzten Mal bearbeitete Record ausgewählt werden.

Das bisherige Programm verwendet die IBX-Komponenten.
Wird nun beim Öffnen des Formulars die Locate-Methode des Datasets verwendet, führt dies zu einer sequentiellen Suche was im vorliegenden Fall gerne mal 10-20 Sekunden dauern kann (bevor jemand schreit, es sind auch berechnete Felder in der Tabelle. Die kann ich aber nicht einfach mal so rauswerfen).

Lösungsidee:
Meine Idee war statt IBX die IBObjects-Komponenten zu verwenden, da diese versprachen, bei LOCATE die vorhandenen Indizies zu verwenden.

Ergebnis bisher:
Gesagt-getan, gebracht hat es nichts, auch die IBObjects führen schließlich einen sequentiellen Abruf der Datenmenge durch.

Betrachtung:
Nach sehr intensiver Suche ist mein derzeitiger Wissensstand der, daß Firebird selbst nur einen sequentiellen Abruf von Ergebnissen erlaubt. Ein explizites Navigieren (Cursorpos) geht gar nicht innerhalb der Verbindung Client-Server.

Nötig für mein Projekt wäre folgendes: Ermittle anhand der Suchkriterien die Nummer des Datensatzes in der Ergebnismenge, positioniere serverseitig dorthin und hole die X Sätze davor und danach für die Darstellung im DBGrid des Clients.

Das scheint wie gesagt nicht möglich zu sein.

Nun meine zwei Fragen an diejenigen, die sich vor allem mit IBObjects auskennen:

1) Übersehe ich im oben geschriebenen etwas? Geht es evtl. doch?
2) Beim Studium des Quelltextes von IBObjects fand ich einiges, was vor allem bei Locates speziell den Server beauftragt, wenn entsprechende Indizies existieren.
Die Programmierer von IBObjects werden diese Teile ja nicht ohne Grund dort eingebaut haben. In welchen Fällen nutzen diese?

Ich weiß, daß in IBObjects auch eine recht gute Verwaltung bereits vom Server heruntergeladener Daten stattfindet. Locates in diesen Daten erfolgen nahezu verzögerungsfrei. Das hilft mir aber hier nicht viel weiter, da aufgrund der Struktur der Anwendung oft die Transactions mittels commit beendet werden, also die betr. Tabellen neu geöffnet werden müssen - also ist der Client-Cache erstmal wieder leer.
mandras Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 429
Erhaltene Danke: 107

Win 10
Delphi 6 Prof, Delphi 10.4 Prof
BeitragVerfasst: Di 18.02.14 00:10 
So, nach einiger weiterer Beschäftigung mit diesem Problem denke ich daß ich selbst die passenden Antworten geben kann.
Wer damit Erfahrung hat, kann mir ja eventuell noch dazu etwas sagen.

1) Übersehe ich im oben geschriebenen etwas? Geht es evtl. doch?

Nein, da Firebird wirklich nur sequentielles Abrufen des Ergebnis-Puffers erlaubt ohne Navigation darin.

2) Beim Studium des Quelltextes von IBObjects fand ich einiges, was vor allem bei Locates speziell den Server beauftragt, wenn entsprechende Indizies existieren.
Die Programmierer von IBObjects werden diese Teile ja nicht ohne Grund dort eingebaut haben. In welchen Fällen nutzen diese?

Diese Teile in IBObjects dienen dazu, bei einem Locate vom Server die passenden Sätze zu ermitteln und die Ergebnisse dann für die Weitersuche in den evtl. schon abgerufenen Daten zu verwenden.
Blup
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 173
Erhaltene Danke: 43



BeitragVerfasst: Mi 26.03.14 10:35 
Wichtig ist KeyLinks selbst zu definieren, als Beispiel:
ausblenden Quelltext
1:
2:
3:
4:
5:
SQl.Strings        = ('select k.* from t_kunden k')
KeyLinks.Strings   = ('k.id')
KeyLinksAutoDefine = False
RefreshAction      = raKeepDataPos
CommitAction       = caRefreshKeys

Um das Locate kümmert sich dann schon die Query.
mandras Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 429
Erhaltene Danke: 107

Win 10
Delphi 6 Prof, Delphi 10.4 Prof
BeitragVerfasst: Do 27.03.14 00:54 
Danke blup für Deine Antwort,

es hilft nichts. Wie ich schon schrieb:
Es geht um das erste Locate direkt nach dem Öffnen des Datasets.
Da sind die Caches noch leer, also muß auch IBO sequentiell einlesen bis es den ersten passenden Satz findet,
da Firebird es leider nicht ermöglicht, innerhalb eines Result Sets zu navigieren außer eben jeweils einen oder mehrere Sätze einzulesen.

Der Programmierer von IBO hat mir noch Hilfe zugesagt, aufgrund der Zeitdifferenz müssen wir aber mal einen passenden Termin absprechen für eine Live Session.
Aber auch da bin ich skeptisch ob er noch einen hilfreichen Tipp hat, da ich mich ja schon vorher durch die FB API und den IBO Quelltext durchgekämpft habe.