![]() |
Datenbank: Firebird • Version: 2.1.3 • Zugriff über: Zeos 6.6.6
Wie Firebird richtig abfragen weil drucken extrem langsam..
Problem:
Das drucken ist extrem langsam... Situation: Ich hab Zugriff via Zeos 6.6.6 ZConnction und ZQuerys auf eine GDB / Reportbuilder 9.3 bekommt Daten via TppDBPipelines Momentaner Ablauf Ein User selektiert Datensätze in der Hauptdatenbank (DBGrid) Ich geh die selektierten Datensätze einem nach dem anderen durch. Dabei wird bei "AfterScroll" der Hauptdatenbank die SubDatenbank 1 via "Select from.." gefiltert.. Die SubDatenbank 2 wird bei "AfterScroll SubDatenbank 1" gefiltert Die SubDatenbank 3 wird bei "AfterScroll SubDatenbank 2" gefiltert Die SubDatenbank 4 wird bei "AfterScroll SubDatenbank 3" gefiltert Das ganze ist bei großen Datenbänke extrem langsam (besonders bei Netzwerk-Clients). Frage: Wie sollte ich (richtigerweise) das Konzept abändern - um die bestmöglichste Performance zu gewinnen ? Vielen Dank für Hinweise Erich Nur als Info: ZConnection <-> ZQuerys <-> Datasets <-> ReportPipelines liefern Daten für den Report: Hauptdatenbank: Aufträge SubDatenbank 1: Verwendete Materialien SubDatenbank 2: Gefahrenstoffdatenblätter pro Material SubDatenbank 3: Mitarbeiterdatenblätter pro Gefahrenstoffdatenblatt SubDatenbank 4: Dokumente pro Mitarbeiterdatenblatt |
AW: Wie Firebird richtig abfragen weil drucken extrem langsam..
Entscheidend sind die Indexe auf den Feldern.
Fremdschlüsselfelder sollten in aller Regel einen Index besitzen. Man müsste mindestens mal deine SQL-Abfragen kennen um einen Rat zu geben, auf welchen Feldern ausserdem ein Index liegen sollte. Ganz grob wären dies alle Felder, die in einer WHERE-Bedingung angesprochen werden. Es hängt aber vom Einzelfall ab, denn ein Index beschleunigt zwar die Abfragen, bremst die Datenbank aber auch beim Einbuchen von Datensätzen (und bläht die DB auf). |
AW: Wie Firebird richtig abfragen weil drucken extrem langsam..
Wie wäre es denn das Problem zu zerlegen?
Wenn ich das richtig verstanden habe, ist da zunächst die Abfrage, an die sich der Ausdruck anschließt. Ist die ganze Sache denn auch langsam, wenn z.B. die Ergebnisse in einer Datei gespeichert werden? Und über welche Datenmenge reden wir hier eigentlich? Meist ist die Strecke von der DB zum Client der Flaschenhals. Wenn da 100 MB über die Leitung müssen, dann kann das schonmal dauern. Gruß K-H |
AW: Wie Firebird richtig abfragen weil drucken extrem langsam..
Hallo shmia und p80286,
danke für die Informationen. Indexes hab ich, denk ich mal, richtig gesetzt, und die Datenbankstruktur ist, na ja.. wie soll ich sagen... eine "gewachsene Geschichte" ... da mal was dazu, dort mal was weg.. aber passend. Ein paar Zeilen hab ich für das "Grid select" gefunden, das die ganze Sache wieder ein bisserl schneller macht: Quelle: ![]()
Delphi-Quellcode:
procedure TfrmMainData.Button1Click(Sender: TObject);
var si : SmallInt; // loop counter sl : tStringList; // temporary storage begin sl := tStringList.Create; try // First, get the selected ID Values. with sl, dbGrid1, DataSource.DataSet do if SelectedRows.Count > 0 then begin add( 'where' ); for si := 0 to SelectedRows.Count - 1 do begin GotoBookMark( pointer( SelectedRows.Items[ si ] ) ); add( 'o.CustNo = ' + fieldByName( 'CustNo' ).asString ); if si < SelectedRows.Count - 1 then add( ' OR ' ); end; end; // Now, revise the query with dmMainData.Query1 do begin if active then close; SQL.clear; SQL.add( 'select distinct * from orders o' ); SQL.AddStrings( sl ); Open; end; finally freeAndNil( sl ); end; end; |
AW: Wie Firebird richtig abfragen weil drucken extrem langsam..
Ein
SQL-Code:
und fehlende Einschränkungen(
select *
SQL-Code:
) führen oft zu Performanceproblemen
where
Besonders whwn man dies dann rekursiv macht |
AW: Wie Firebird richtig abfragen weil drucken extrem langsam..
Ist der "Grid Select Code" als Beispiel zu verstehen oder verwendest Du das so?
ich bin kein FB Kenner, aber ich würde - OR in der Whereclause eher vermeiden, alternativ IN ()/ Mengenoperator nehmen. - Parameter verwenden, statt verkettete Statements (weiß nicht, wie FB das macht, aber Oracle würde alle diese Abfragen (bis 4 Unterebene immer wieder parsen!) Und etwas spezifischeres als alle Orders zu selektieren, könnte auch hilfreich sein. |
AW: Wie Firebird richtig abfragen weil drucken extrem langsam..
Jedes DBMS würde neu Parsen, wenn es einen neuen Abfragestring bekommt.
|
AW: Wie Firebird richtig abfragen weil drucken extrem langsam..
@jobo
Ist der Beispiels-Code von ![]() Or / IN ... gibt es da Performance-Unterschiede ? Select * from .. ist bei mir natürlich: Select Feldname, Feldname, Feldname.. @Allgemein Wie im ersten Posting beschrieben gibt es ja verschiedene "Ebenen" der Tabellen: (..ups ich sehe grade, dass ich überall "Datenbank" anstelle "Tabelle" geschrieben hab)
Wenn in der Haupttabelle sagen wir mal 30 Datensätze markiert werden, wird die Subtable 1 30x per haupttable.afterscroll mit "Select * from Subtable 1 where ID = haupttable.ID .." gefiltert.. Wenn in jeder Teilmenge von Subtable 1 - 10 Records überbleiben, wird Subtable2 300x via SQL Statement gefiltert.. Gibts da irgendwie einen Trick, das zu umgehen ? Subtable2 nur einmal filtern und mit locate oder bookmarks die Daten der Teilmenge zum drucken "markiere" ? Vielen Dank Erich |
AW: Wie Firebird richtig abfragen weil drucken extrem langsam..
OR / IN
Ich kann das nur erfahrungsgemäß beantworten, da ich nicht mit FB arbeite. OR macht gerne mal mehrere Scans (also grob für jeden OR Fall) IN hat natürlich eine andere Funktionalität, die es aber dem Analyzer erlaubt, etwas zielgerichteter zu arbeiten. IN würde aber in Deinem Fall passen. Letztlich müsstest Du Dir die "Mühe" machen, Ausführungspläne der beiden Varianten zu vergleichen. Ist natürlich statisch dann, die Unterschiede evtl. marginal, aber die Menge machts dann halt. Ansonsten: Bei Queries oder auch gerade bei Report Komponenten wird gerne mal ungewollt die Datenmenge ohne Filter geöffnet (wenn mit Filterproperties gearbeitet wird, z.B. sofort bei "Open"). Und bei harmlosen Reports mit einer Untermenge fällt das dann u.U. erst im Produktivbetrieb auf oder wenn dutzende User diese Reports aufrufen. In der Richtung würde ich mal den Code, das Verhalten untersuchen. Locate & Co Denkbar wäre es, alle 4 Mengen vollständig zu öffnen, mittels Query und gleich richtig sortiert. Dann könnte man Locate oder sogar nur mit Next arbeiten. Könnte schnell sein, würde ich aber als Notlösung sehen. Wenn Du Dir sicher bist, dass Indizierung und alles andere stimmt, kannst Du auch probehalber 4 Datenquellen mit Datasource und Grids untereinander hängen und mal "sehen", wo die Performance bleibt. Wenn das flott geht, dann Report Kompos oder deren Verdrahtung genauer anschauen. Ich würde mit den Ausführungsplänen anfangen. Das ist die Basis und häufig denkt man nicht so, wie der QueryAnalyzer der DB "denkt". |
AW: Wie Firebird richtig abfragen weil drucken extrem langsam..
Dies ist kein Datenbankproblem. Das Thema war eher scrollen im Grid. Wenn man bei jedem nicht relevanten Datensatz die abhängige Abfrage anfordert, kann ein nicht in Memory DBMS nicht hinterherkommen. Es muss eigentlich nur der Datensatz angefordert werden, bei dem der Nutzer eine Pause im Scrolling einlegt.
Vorschlag: Im OnScroll-Event einen Tiner reseten und die Unterabfrage und Timer disabled im Timer-Event. Grüße in die Runde |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:16 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz