Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Geschwindigkeit beim auslesen verbessern (https://www.delphipraxis.net/39942-geschwindigkeit-beim-auslesen-verbessern.html)

Grumble 9. Feb 2005 11:29

Datenbank: Firebird • Version: 1.5.1 • Zugriff über: sql

Geschwindigkeit beim auslesen verbessern
 
hallo,

also folgendes problem... ich lese aus einer tabelle im moment 6500 datensaetze...
jeder datensatz ist eine zeile mit ; getrennter daten, welche ich dann in ein topgrid schreibe...
mein programm verwaltet projekte die alle solche daten enthalten koennen, wenn ich nun ein projekt mit 6500 daten anzeigen will, dauert es recht lang, wechsle ich aber zu einem projekt mit gar keinen oder wenig daten dauert es immer noch lang,
verlangsamt sich der datenzugriff oder sonst was, je mehr daten in meiner db stehen, weshalb? habe ich wenig daten in meiner db, geht der wechsel zwischen den projekten schnell... hat wer ne idee?

so lese ich aus und schreibe ins grid
Delphi-Quellcode:
// auslesen tabelle asset_data
  c:=0;
  dataexist:=false;
  DM.ZQ.SQL.Clear;
  DM.ZQ.SQL.add('SELECT * FROM ASSET_DATA;');
  DM.ZQ.Open;
  DM.ZQ.First;
  while not DM.ZQ.Eof do
  begin
  if caid = DM.ZQ.Fieldbyname('ASSET_ID').asinteger then
  begin
    dataexist:=true;
    break;
  end;
  dm.ZQ.Next;
  end; //while
if dataexist then
  begin
  DM.ZQ.First;
  while not DM.ZQ.Eof do
  begin
    if caid = DM.ZQ.Fieldbyname('ASSET_ID').asinteger then
    begin
      c:=c+1;
      grd_asset.Rows:=grd_asset.Rows+1;
      s:= DM.ZQ.Fieldbyname('DATA').asString;
      templist:=Tstringlist.create;
      templist.Delimiter:=';';
      templist.DelimitedText:=s;
      if c = 1 then grd_asset.Cols:=templist.Count;
      for i:=1 to templist.Count do
      grd_asset.Cell[i,c]:=templist.Strings[i-1];
    end;
    DM.ZQ.Next;
  end;
  end; //if dataexist

ibp 9. Feb 2005 11:38

Re: Geschwindigkeit beim auslesen verbessern
 
du solltest deine abfrage optimieren, indem du nur datensätze holst die du brauchst, also asset_id=caid!

Delphi-Quellcode:
// auslesen tabelle asset_data
  c:=0;
  dataexist:=false;
  DM.ZQ.SQL.Clear;
  DM.ZQ.SQL.add('SELECT * FROM ASSET_DATA');
  DM.ZQ.SQL.add('where ASSET_ID='+inttostr(caid)); // vorselektieren!
  DM.ZQ.Open;
  if not DM.ZQ.Eof then
    DM.ZQ.First
  else
    exit; // keine daten vorhanden
  while not DM.ZQ.Eof do
  begin
    c:=c+1;
    grd_asset.Rows:=grd_asset.Rows+1;
    s:= DM.ZQ.Fieldbyname('DATA').asString;
    templist:=Tstringlist.create;
    templist.Delimiter:=';';
    templist.DelimitedText:=s;
    if c = 1 then
      grd_asset.Cols:=templist.Count;
    for i:=1 to templist.Count do
      grd_asset.Cell[i,c]:=templist.Strings[i-1];
    DM.ZQ.Next;
  end;
  end; //if dataexist

Sharky 9. Feb 2005 11:39

Re: Geschwindigkeit beim auslesen verbessern
 
Hai Grumble,

da fallen mir zwei Sachen auf in deinem Code.

1) Wofür ist die erste Schleife? Du prüfst doch nur ob im Feld ASSET_ID ein bestimmter Wert vorkommt. Mache das doch gleich in deinem Query:

2) Du erzeugst für jede Zeile aus der Tabelle eine neue TStringList. Das haut dir doch den Speicher voll.

Delphi-Quellcode:
// auslesen tabelle asset_data
  c:=0;
  dataexist:=false;
  DM.ZQ.SQL.Clear;
  DM.ZQ.SQL.add('SELECT * FROM ASSET_DATA WHERE ASSET_id = ' + IntToStr (caid));
  DM.ZQ.Open;
  DM.ZQ.First;
{
  while not DM.ZQ.Eof do
  begin
  if caid = DM.ZQ.Fieldbyname('ASSET_ID').asinteger then
  begin
    dataexist:=true;
    break;
  end;
  dm.ZQ.Next;
  end; //while
  if dataexist then
  begin
  DM.ZQ.First;
}
 templist:=Tstringlist.create;
 try
   templist.Delimiter:=';';
    while not DM.ZQ.Eof do
    begin
//      if caid = DM.ZQ.Fieldbyname('ASSET_ID').asinteger then
//      begin
        c:=c+1;
        grd_asset.Rows:=grd_asset.Rows+1;
        s:= DM.ZQ.Fieldbyname('DATA').asString;
        templist.DelimitedText:=s;
        if c = 1 then grd_asset.Cols:=templist.Count;
        for i:=1 to templist.Count do
          grd_asset.Cell[i,c]:=templist.Strings[i-1];
//      end;
    DM.ZQ.Next;
  end;
 finally
   templist.Free;
 end;
//  end; //if dataexist

Grumble 9. Feb 2005 11:43

Re: Geschwindigkeit beim auslesen verbessern
 
:wall: ja richtig ... die stringlist ..
weshalb bau ich hier if bedingungen ein wenn ueber query geht :wall: naja ich hab ja erst angefangen mit dem sql kram ...

super danke euch fuer die tips

Sharky 9. Feb 2005 11:47

Re: Geschwindigkeit beim auslesen verbessern
 
Kleiner Nachtrag:

Das müsste doch eigentlich so aussehen:
Delphi-Quellcode:
.
.
        for i:=1 to templist.Count -1  do // Der Index geht von 0 bis count -1
          grd_asset.Cell[i,c]:=templist.Strings[i-1];
.
.

Grumble 9. Feb 2005 11:49

Re: Geschwindigkeit beim auslesen verbessern
 
deswegen aber
Delphi-Quellcode:
grd_asset.Cell[i,c]:=templist.Strings[i-1];
i-1

Sharky 9. Feb 2005 11:51

Re: Geschwindigkeit beim auslesen verbessern
 
Ups. Stimmt. Aber es ist verwirrend es so zu machen. Ich würde das immer in der Schleife angeben. Dann sieht jeder der den Code list wast Du machst.

Airblader 9. Feb 2005 11:51

Re: Geschwindigkeit beim auslesen verbessern
 
Übrigens ist es generell schlecht den Stern * zu nehmen.

auf PHP-FAQ kann man nachlesen, warum nicht.
Stattdessen sollte man die Felder holen, die man braucht.

air

Grumble 9. Feb 2005 11:54

Re: Geschwindigkeit beim auslesen verbessern
 
von daher hast du sicher recht, ich habs mir dummerweise andersrum angewoehnt...

koennte es evtl. auch noch sein dass das anfuegen einer reihe ans grid die sache verlangsamt? kann man die anzahl der datensaetze wo where asset_ID= caid ist so auch noch schnell rausbekommen, dann koennt ich die gridzeilenanzhal vorher festlegen, vielleicht bringt das auch noch mal geschwindigkeit...

alcaeus 9. Feb 2005 12:01

Re: Geschwindigkeit beim auslesen verbessern
 
Hallo Grumble,

versuchs mal mit
Delphi-Quellcode:
DM.ZQ.RecordCount
Greetz
alcaeus

Sharky 9. Feb 2005 12:11

Re: Geschwindigkeit beim auslesen verbessern
 
Eventuell würde es auch einiges bringen für jede Zeile und Spalte des SG vor dem füllen ein BeginUpDate zu machen und nach dem Füllen ein EndUpdate:

Delphi-Quellcode:
procedure SGBeginUpdate (sg : TStringGrid);
var
  ndx : Integer;
begin
  for ndx := 0 to sg.RowCount-1 do
  begin
    sg.Rows[ndx].BeginUpdate;
  end;
  for ndx := 0 to sg.ColCount -1 do
  begin
    sg.Cols[ndx].BeginUpdate;
  end;
end;

procedure SGEndUpdate (sg : TStringGrid);
var
  ndx : Integer;
begin
  for ndx := 0 to sg.RowCount-1 do
  begin
    sg.Rows[ndx].EndUpdate;
  end;
  for ndx := 0 to sg.ColCount -1 do
  begin
    sg.Cols[ndx].EndUpdate;
  end;
end;


.
.
    grd_asset.Rows:= DM.ZQ.RecordCounte + 1; // Zeilenanzahl
    while not DM.ZQ.Eof do
    begin
        c:=c+1;

        s:= DM.ZQ.Fieldbyname('DATA').asString;
        templist.DelimitedText:=s;
        if c = 1 then
        begin
          grd_asset.Cols:=templist.Count; // Spaltenanzahl
          SGBeginUpDate (grd_asset); // BeginUpdate für das SG
        end;
        for i:=1 to templist.Count do
          grd_asset.Cell[i,c]:=templist.Strings[i-1];
//      end;
    DM.ZQ.Next;
    end;
    SGEndUpDate (grd_asset); // EndUpdate für das SG
.
.
Vorher müssen natürlich die Spalten und Zeilenanzahlen bekannt sein.

Grumble 9. Feb 2005 12:14

Re: Geschwindigkeit beim auslesen verbessern
 
verzeih meine unwissenheit, aber wozu diese update?

btw: recordcount war ne gute idee, bin mit der performance jetzt zufrieden :)

Sharky 9. Feb 2005 12:20

Re: Geschwindigkeit beim auslesen verbessern
 
Zitat:

Zitat von Grumble
verzeih meine unwissenheit, aber wozu diese update?...

Was gibt es da zu verzeihen?

Wenn Du eine visuele Komponente (StringGrit, ListBox, ListView usw) mit Daten füllst wird sie bei jedem neuen Eintrag auch neu gezeichnet. Durch das BeginUpdate wird dieses verhindert. Das bedeutet während dem füllen wird das Grid nicht neu gezeichnet. Erst nach dem EndUpdate wird dieses gemacht. Dies kann auch einige Sekunden einsparen.

shmia 9. Feb 2005 12:21

Re: Geschwindigkeit beim auslesen verbessern
 
Kleine Optimierungen: :wink:
Delphi-Quellcode:
  c:=0;
  dataexist:=false;
// DM.ZQ.SQL.Clear; <== ist überflüssig wenn Zuweisung auf SQL.Text folgt
  DM.ZQ.SQL.Text := 'SELECT * FROM ASSET_DATA WHERE ASSET_id = ' + IntToStr (caid);
  DM.ZQ.Open;
//  DM.ZQ.First; <== ist überflüssig, da nach Open die Datenmenge immer auf dem 1. Record steht
  if DM.ZQ.IsEmpty then  // <== Prüfung mit IsEmpty ist am "saubersten"
     Exit;  // keine Daten gefunden


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:19 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