AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Optimieren der Datenbankabfragen für Reportpipelines
Thema durchsuchen
Ansicht
Themen-Optionen

Optimieren der Datenbankabfragen für Reportpipelines

Ein Thema von erich.wanker · begonnen am 9. Sep 2009 · letzter Beitrag vom 29. Sep 2009
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von erich.wanker
erich.wanker

Registriert seit: 31. Jan 2008
Ort: im schönen Salzburger Land
454 Beiträge
 
Delphi XE4 Professional
 
#1

Optimieren der Datenbankabfragen für Reportpipelines

  Alt 9. Sep 2009, 14:22
Datenbank: Firebird • Version: 2.1.0 • Zugriff über: ZEOS
Hallo Leute,

Situation:
WinXP / Delphi 7 / Firebird 2.1 / Zeos / Reportbuilder 9.0

Eine GDB Datei mit ca 30 Tabellen...
Tabelle 1: Kunden
Tabelle 2: Details
Tabelle 3: Arbeiten
Tabelle 4: Arbeitsbeschreibung
Tabelle 5: Beschreibungdokumente
...



Beispiel Datenstruktur:
Delphi-Quellcode:
Kunde1
     Detail 1
         Arbeit 1
         Arbeit 2
         Arbeit 3
             Arbeitsbeschreibung 1
                Beschreibungsdokument 1
                Beschreibungsdokument 2
     Detail 2
         Arbeit 1
         Arbeit 2
     Detail 3
     Detail 4
         Arbeit 1
             Arbeitsbeschreibung 1
Kunde 2
....
Wenn ich nun Daten via Reportbuilder drucken will geh ich folgendermaßen vor:

Tabelle1 - afterScroll .. Select * from Tabelle 2 where tabelle2.Verknüpft_mit = tabelle1.aktuelleNummer
Tabelle2 - afterScroll .. Select * from Tabelle 3 where tabelle3.Verknüpft_mit = tabelle2.aktuelleNummer
Tabelle3 - afterScroll .. Select * from Tabelle 4 where tabelle4.Verknüpft_mit = tabelle3.aktuelleNummer
Tabelle4 - afterScroll .. Select * from Tabelle 5 where tabelle5.Verknüpft_mit = tabelle4.aktuelleNummer

.. jede Tabelle hat eine Pipeline, die ich dann via Subreports zu Papier bringe ..

aber das dauert ! ... kann ich (die Tabellenstruktur muss ich belassen wie sie ist) .. durch irgendeine andere Art der Datenselektierung das ganze schneller machen ... ? im Moment werden ja extrem viele SQL Statements gefeuert, wenn der Reportbuilder durch die Tabellen fährt .. kann ich was mit Bookmarks machen oder so ?

Vielen Dank

Erich
Erich Wanker - for life:=1971 to lebensende do begin ..
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: Optimieren der Datenbankabfragen für Reportpipelines

  Alt 9. Sep 2009, 14:50
-kein Select *
-Wie sihet es mit den Indizes aus?
-SP
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von erich.wanker
erich.wanker

Registriert seit: 31. Jan 2008
Ort: im schönen Salzburger Land
454 Beiträge
 
Delphi XE4 Professional
 
#3

Re: Optimieren der Datenbankabfragen für Reportpipelines

  Alt 9. Sep 2009, 14:56
hi,

-kein Select *
via reportdesigner könnte edes x-beliebige feld gedruckt werden .. ich kann nicht im vorfeld definieren, welche.

-Wie sihet es mit den Indizes aus?
indizes hab ich nur eine interne nummer, sonst nix

SP? ..
Erich Wanker - for life:=1971 to lebensende do begin ..
  Mit Zitat antworten Zitat
hoika

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

Re: Optimieren der Datenbankabfragen für Reportpipelines

  Alt 9. Sep 2009, 15:04
Hallo,

jedes Feld eines where biw. join wird indiziert.
Das wären also mind. Verknüpft_mit und aktuelleNummer

Ausserdem sollte die Endung nicht GDB heissen,
besonders unter XP nicht.
XP erzeugt bei jedem Öffnen eine "Sicherheitskopie".


Heiko
Heiko
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#5

Re: Optimieren der Datenbankabfragen für Reportpipelines

  Alt 9. Sep 2009, 15:07
Hallo,

beim Einsatz von TTable könnte das in der Form funktionieren:

Delphi-Quellcode:
Table2.Filtered := False;
Table2.Filter := 'id = ' + Table1.FieldByName('ID').AsString;
Table2.Filtered := True;
Table3.Filtered := False;
Table3.Filter := 'id = ' + Table1.FieldByName('ID').AsString;
Table3.Filtered := True;
Table4.Filtered := False;
Table4.Filter := 'id = ' + Table1.FieldByName('ID').AsString;
Table4.Filtered := True;
Table5.Filtered := False;
Table5.Filter := 'id = ' + Table1.FieldByName('ID').AsString;
Table5.Filtered := True;
d. h.: Jede der Detailtabellen enthält alle Daten (müsste bei Querys auch gehen) und beim Scrollen wird der Filter auf den entsprechenden Fremdschlüssel gesetzt.

Alternativ schau Dir mal Table1.Lookup() an, immer davon ausgehend, dass Zeos entsprechende Implementierungen enthält.
Eventuell könnte auch noch Table1.SetRange eine Alternative sein.

Und: Wie sieht die Datenmenge aus, gibt es jeweils für die Schlüssel einen passenden Index? (Das bitte zuerst abklären, kann extrem zur Beschleunigung beitragen.)
Der Index auf die interne Nummer ist das der Index auf Verknüpft_mit und aktuelleNummer, wenn nicht, bitte unbedingt diese Spalten mit 'nem Index versehen.
  Mit Zitat antworten Zitat
Benutzerbild von erich.wanker
erich.wanker

Registriert seit: 31. Jan 2008
Ort: im schönen Salzburger Land
454 Beiträge
 
Delphi XE4 Professional
 
#6

Re: Optimieren der Datenbankabfragen für Reportpipelines

  Alt 9. Sep 2009, 15:37
..nehmen wir noch mal die Demostruktur:
Delphi-Quellcode:
Kunde1
     Detail 1
         Arbeit 1
         Arbeit 2
         Arbeit 3
             Arbeitsbeschreibung 1
                Beschreibungsdokument 1
                Beschreibungsdokument 2
     Detail 2
         Arbeit 1
         Arbeit 2
     Detail 3
     Detail 4
         Arbeit 1
             Arbeitsbeschreibung 1
Kunde 2
wenn die Tabelle "Kunden" selectiert wird, wird anschließend die Tabelle "Detail" gefiltert (wegen afterScroll),
dadurch wird anschließend die Tabelle "Arbeit" gefiltert (wegen afterScroll),
dadurch wird anschließend die Tabelle "Arbeitsbeschreibung" gefiltert (wegen afterScroll),
dadurch wird anschließend die Tabelle "Beschreibungsdokument " gefiltert (wegen afterScroll),
u.s.w.
Wenn nun Arbeit 2 angesprungen wird, fängt die "afterScroll Sql-Aktion" ja wieder an..

Ich stell mir eher so was vor:
wenn die Tabelle "Kunden" selectiert wird,
wird anschließend jeder Eintrag von "Details" selektiert, der mit dem Kunden in Verbindung steht.
Anschließend wird jeder Eintrag von "Arbeit" selektiert, der mit dem Kunden in Verbindung steht.
Anschließend wird jeder Eintrag von "Arbeitsbeschreibung" selektiert, der mit dem Kunden in Verbindung steht.
Anschließend wird jeder Eintrag von "Beschreibungsdokument " selektiert, der mit dem Kunden in Verbindung steht.

und im afterScroll so was ähnliches wie:

Delphi-Quellcode:
ppBDEPipeline.ClearBookmarkList;
Tabelle first,
while not Tabelle.EOF do
begin
if Datensatz erfüllt Bedingung then setze Bookmark auf diesen..
Tabelle.next;
end;

Also wird einmal pro Tabelle ein SQL geschossen und der Client hat die gefilterte Datenmänge mal "vor sich"
via Bookmarks sag ich der Pipeline, welche Daten sie drucken soll..

wie könnte ich das "Bookmark setzen" für die Pipeline realisieren ?
Beispiel zur Frage:
Delphi-Quellcode:
Query1 = Select * from Tabelle
Datasource1 ist Verbunden mit Query1
ppDBPipeline1 ist verbunden mit Datasource1

ppBDEPipeline1.ClearBookmarkList
  Schleife durch das Query
    if Query1.fieldbyname('xy').asstring = 'yeppthen setze ein Bookmark für die Pipeline
  Schleife ende
Erich Wanker - for life:=1971 to lebensende do begin ..
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#7

Re: Optimieren der Datenbankabfragen für Reportpipelines

  Alt 9. Sep 2009, 16:24
Hallo,
das von Dir gewünschte Verhalten erreichst Du doch mit table.Filter. Jede Tabelle bekommt in ihr AfterScroll das Setzen des Filter zur von ihr abhängigen Detailmenge.

Table1.Afterscroll setzt also den Filter für Table2, deren Afterscoll den Filter für Table3... .

Alle Tabellen (Querys) enthalten jedoch die gesamte Ergebnismenge analog zu select * from Tabelle, durch das Setzen der Filter im AfterScroll wird nur die für das Programm sichtbare Menge reduziert, beim Setzen von Table.Filtered := False ist sofort wieder die gesamte Datenmenge der Tabelle sichtbar.

SetRange verhält sich analog. Die Gesamtmenge der Daten muss daher nicht mehrfach von der Datenbank geliefert werden, ebensowenig ist ein Abholen der jeweils benötigten Teilmenge von der Datenbank erforderlich.

Mach Dir doch mal eine "Demo"-Applikation mit ein paar DBGrids für ein halbes dutzend Tabellen, wähle für alle Tabellen am Anfang die gesamte Datenmenge aus und setze in den jeweiligen AfterScroll-Ereignissen die Filter für die Detailtabellen. Nach dem Setzen der Filter auf Filtered := True ist eventuell noch ein First erforderlich, um das AfterScoll auszulösen.

Damit solltest Du Dir dann zumindest einen kleinen Überblick über das Laufzeitverhalten verschaffen können und sehen, ob die richtigen Teilmengen zusammengesucht werden.
  Mit Zitat antworten Zitat
Benutzerbild von erich.wanker
erich.wanker

Registriert seit: 31. Jan 2008
Ort: im schönen Salzburger Land
454 Beiträge
 
Delphi XE4 Professional
 
#8

Re: Optimieren der Datenbankabfragen für Reportpipelines

  Alt 9. Sep 2009, 16:53
@nahpets

Hallo, vielen Dank für deine Hilfe.

Ich würd sehr ungern meine SQl-Querys gegen Table's austauschen.
Funktionieren tut das ganze ja - nur halt zu langsam ..

Ich denk, das grad die Query -SQLStatements (oder auch Table -Filter) die Hauptbremsen sind - weil si so oft vorkommen.

Die Tables würden mir ja die komplette Datenbank (alle Tabellen) auf den Client holen - (Performance vom Netz!) - vie SQL Statemnts hol ich mir wenigstens nur die "affected Rows" - nur halt zu oft ..

Erich
Erich Wanker - for life:=1971 to lebensende do begin ..
  Mit Zitat antworten Zitat
franktron

Registriert seit: 11. Nov 2003
Ort: Oldenburg
1.446 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#9

Re: Optimieren der Datenbankabfragen für Reportpipelines

  Alt 9. Sep 2009, 17:00
Also ich kenn Report Builder nicht aber in Fastreport geht das ganze so

Report

<masterdatail>Kunde1
<subdateil>Detail 1
. Arbeit 1
. Arbeit 2
. Arbeit 3
. Arbeitsbeschreibung 1
. Beschreibungsdokument 1
. Beschreibungsdokument 2
. Detail 2
. Arbeit 1
. Arbeit 2
. Detail 3
. Detail 4
. Arbeit 1
. Arbeitsbeschreibung 1
. Kunde 2

Die . sind für weiter Details

und dann im OnBeforePrint jeweils die Query Filtern (für jedes Detail eine eigene Query)
Frank
Tux sein Lieblingsquellcode
While anzfische<TuxSatt do begin
Fisch:=TFisch.Create; Tux.EssenFisch(Fisch); Fisch.Free;inc(anzfische); end;
  Mit Zitat antworten Zitat
hoika

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

Re: Optimieren der Datenbankabfragen für Reportpipelines

  Alt 10. Sep 2009, 07:21
Hallo,

ich habe mir übrigens angewohnt,
jede Query durch den IBPlanalyzer zu jagen.
Der funktioniert bis auf einige Ausnahmen auch noch mit FB2.X.

Wie der Name sagt, analysiert er die Queries
und zeigt Probleme an.

Zur Not kann man auch IBExpert (Personal) dafür nehmen.
Dort wird der Plan aber nur als Text angezeigt.

Sobald aber irgendwo PLAN NATURAL steht
(also FullTable Scan), fehlt meistens ein Index.


Heiko
Heiko
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

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

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

Gehe zu:

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