AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi VST mit ca. 50.000 Datensätze verdammt langsam, warum???
Thema durchsuchen
Ansicht
Themen-Optionen

VST mit ca. 50.000 Datensätze verdammt langsam, warum???

Ein Thema von Piro · begonnen am 7. Dez 2009 · letzter Beitrag vom 8. Dez 2009
Antwort Antwort
Seite 1 von 3  1 23      
Benutzerbild von Piro
Piro

Registriert seit: 14. Jul 2003
Ort: Flintbek
810 Beiträge
 
Delphi XE2 Professional
 
#1

VST mit ca. 50.000 Datensätze verdammt langsam, warum???

  Alt 7. Dez 2009, 19:58
Guten Abend,

ich verwende ein VST, um Daten aus einer MS SQL Express 2005 anzuzeigen. Es kann vorkommen, dass das VST um die 50.000 Datensätze erhält. Wenn die Daten ins VST geschrieben werden, dauert es unwahrscheinlich lange (gefühlte 2 Minuten).

Die Daten werden in eine Klasse gespeichert, so wie es im Video-Tutorial vom Stammtisch zu sehen ist.

Folgendes mache ich mit dem VST:
- Haederleiste bekommt einen Hintergrund
- GetText, um die Daten anzuzeigen
- GetImageIndex
- CompareNode

Das ist eigentlich alles. Wenn ich GetText und CompareNode herausnehme. Geht es etwas schneller aber noch nicht schnell genug.

Kann es sein, dass ein VST für solche Datenmengen nicht gemacht ist, weil das VST dann zuviel machen muss und somit langsam wird?

Vielen Dank im voraus.

Sven
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

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

Re: VST mit ca. 50.000 Datensätze verdammt langsam, warum???

  Alt 7. Dez 2009, 20:10
Die Frage ist auch, ob es sinnvoll ist 50 000 Einträge anzuzeigen
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von semo
semo

Registriert seit: 24. Apr 2004
755 Beiträge
 
Delphi 2010 Professional
 
#3

Re: VST mit ca. 50.000 Datensätze verdammt langsam, warum???

  Alt 7. Dez 2009, 20:13
Wie füllst du denn den VST? Per InitNode oder per AddNode?
Nutzt du BeginUpdate und EndUpdate?

Meines Wissens stellen 50.000 Einträge kein Problem dar.
Frage ist auch, welche Daten die in dem Data Record des jeweiligen Nodes hinterlegst.
  Mit Zitat antworten Zitat
generic

Registriert seit: 24. Mär 2004
Ort: bei Hannover
2.416 Beiträge
 
Delphi XE5 Professional
 
#4

Re: VST mit ca. 50.000 Datensätze verdammt langsam, warum???

  Alt 7. Dez 2009, 20:17
das befüllen sollte schnell gehen, wenn du vst.beginupdate und endupdate verwendest, da der vst nur speicher für den zeiger (und natürlich die Nodestruktur) belegen wird.

vermutlich dauert das umkopieren aus der db so lange.

du könntest, wenn du die anzahl der daten kennst, den nodecount setzen und im oninitnode die zeiger setzen.
das geht dann einen tick schneller.
Coding BOTT - Video Tutorials rund um das Programmieren - https://www.youtube.com/@codingbott
  Mit Zitat antworten Zitat
hoika

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

Re: VST mit ca. 50.000 Datensätze verdammt langsam, warum???

  Alt 7. Dez 2009, 20:20
Hallo,

ich würde erst mal ein paar Breakpoints setzen,
um festzustellen, wo er hängt,
und dann mit 1/2-Einträgen testen,
ob der VST zu viel "unternimmt".


Heiko
Heiko
  Mit Zitat antworten Zitat
Benutzerbild von Piro
Piro

Registriert seit: 14. Jul 2003
Ort: Flintbek
810 Beiträge
 
Delphi XE2 Professional
 
#6

Re: VST mit ca. 50.000 Datensätze verdammt langsam, warum???

  Alt 7. Dez 2009, 20:33
Das Programm ist eine Art Verwaltung von Subnetzen mit den jeweilige Wertenbereichen.

Hier meine Datenstruktur:
Delphi-Quellcode:
 type
  TOSubnetDetailsData = class
  private
    //
  public
    id : String;
    ipaddress : String;
    device : String;
    dhcp_exclude : Integer;
    dhcp_mac : String;
    site : String;
    building : String;
    floor : String;
    position : String;
    vlan : String;
    subnetdevice : String;
    description : String;
    sid : String;

    function GetDHCP_ExcludedName: String;
    property dhcp_excludedname : String read GetDHCP_ExcludedName;
  end;
So lade ich die Daten aus der DB in das VST
Delphi-Quellcode:
procedure Tfrm_main.SQLDataToVST_SubnetDetails;
var
 i : Integer;
 SubnetDetailsData : TOSubnetDetailsData;
begin
 vst_network_subnetdetails.Clear;

 DSData.Close;
 DSData.CommandText := 'select network_subnetdetails.id,'+
                               'network_subnetdetails.ipaddress,'+
                               'network_subnetdetails.device,'+
                               'network_subnetdetails.dhcp_exclude,'+
                               'network_subnetdetails.dhcp_mac,'+
                               'network_sites.site,'+
                               'network_subnets.building,'+
                               'network_subnets.floor,'+
                               'network_subnets.position,'+
                               'network_subnets.vlan,'+
                               'network_subnets.device as subnetdevice,'+
                               'network_subnetdetails.description,'+
                               'network_subnetdetails.subnet_id '+
                       'from network_subnets '+
                               'inner join network_subnetdetails on network_subnets.id = network_subnetdetails.subnet_id '+
                               'inner join network_sites on network_subnets.site_id = network_sites.id '+
                       'order by cast(parsename([ipaddress], 4) as int),'+
                                'cast(parsename([ipaddress], 3) as int),'+
                                'cast(parsename([ipaddress], 2) as int),'+
                                'cast(parsename([ipaddress], 1) as int)';
 DSData.Open;
 DSData.First;
 for i := 0 to DSData.RecordCount - 1 do
 begin
   SubnetDetailsData := TOSubnetDetailsData.Create;
   with SubnetDetailsData do
   begin
     id := DSData.FieldByName('id').AsString;
     ipaddress := DSData.FieldByName('ipaddress').AsString;
     device := DSData.FieldByName('device').AsString;
     dhcp_exclude := DSData.FieldByName('dhcp_exclude').AsInteger;
     dhcp_mac := DSData.FieldByName('dhcp_mac').AsString;
     site := DSData.FieldByName('site').AsString;
     building := DSData.FieldByName('building').AsString;
     floor := DSData.FieldByName('floor').AsString;
     position := DSData.FieldByName('position').AsString;
     vlan := DSData.FieldByName('vlan').AsString;
     subnetdevice := DSData.FieldByName('subnetdevice').AsString;
     description := DSData.FieldByName('description').AsString;
     sid := DSData.FieldByName('subnet_id').AsString;
   end;
   vst_network_subnetdetails.AddChild(nil, SubnetDetailsData);
   Application.ProcessMessages;
   DSData.Next;
 end;
 DSData.Close;
end;
Die Abfrage gegen die Datenbank geht schnell und das AddChild dauert seine Zeit. Kann ich da noch etwas optimieren?
Die Struktur und die Methoden sind in Anlehnung an das Stammtisch-Video für VST.

Falls das ein normales Verhalten des VST ist, werde ich den View limitieren.

Sven
  Mit Zitat antworten Zitat
Benutzerbild von wicht
wicht

Registriert seit: 15. Jan 2006
Ort: Das schöne Enger nahe Bielefeld
809 Beiträge
 
Delphi XE Professional
 
#7

Re: VST mit ca. 50.000 Datensätze verdammt langsam, warum???

  Alt 7. Dez 2009, 20:37
Fehlt das BeginUpdate/EndUpdate in der Prozedur, oder ist das irgendwo anders?
Mein Tree ist mit 27.000 Nodes auch blitzschnell, ich denke nicht, dass es am Tree liegt.

HTH
http://streamwriter.org

"I make hits. Not the public. I tell the DJ’s what to play. Understand?"
  Mit Zitat antworten Zitat
Benutzerbild von semo
semo

Registriert seit: 24. Apr 2004
755 Beiträge
 
Delphi 2010 Professional
 
#8

Re: VST mit ca. 50.000 Datensätze verdammt langsam, warum???

  Alt 7. Dez 2009, 20:38
Im GetText sollte eigentlich der Text geladen werden, nicht vorher.
Wenn du 50.000 Datensätze hast und 12 strings pro record - da möchte ich mal den Speicherverbauch sehen.

Auch sehe ich kein BeginUpdate und kein EndUpdate.

Normalerweise sollte man einfach per VST.RootNodeCount := DataSet.RecordCount die Anzahl der Nodes festlegen und im InitNode die RecordNo setzen und dann im GetText die Daten zu der RecordID auslesen.
  Mit Zitat antworten Zitat
Benutzerbild von Piro
Piro

Registriert seit: 14. Jul 2003
Ort: Flintbek
810 Beiträge
 
Delphi XE2 Professional
 
#9

Re: VST mit ca. 50.000 Datensätze verdammt langsam, warum???

  Alt 7. Dez 2009, 20:47
In dem Videotutorial gab es kein BeginUpdate und EndUpdate. Wozu ist das relevant?

Delphi-Quellcode:
procedure Tfrm_main.FormCreate(Sender: TObject);
begin
 ...
 // Initialisierung - Speichergröße des Node bekanntgeben sonst Exceptions
 vst_network_subnetdetails.NodeDataSize := sizeof(TOSubnetDetailsData);
 ..

Hier meine Methoden für das VST:
Delphi-Quellcode:
procedure Tfrm_main.vst_network_subnetdetailsAdvancedHeaderDraw(
  Sender: TVTHeader; var PaintInfo: THeaderPaintInfo;
  const Elements: THeaderPaintElements);
begin
 if hpeBackground in Elements then
 begin
   PaintInfo.TargetCanvas.Brush.Bitmap := img_bg_20.Picture.Bitmap;

   if PaintInfo.Column <> nil then
     DrawFrameControl(PaintInfo.TargetCanvas.Handle, PaintInfo.PaintRectangle,DFC_BUTTON,DFCS_FLAT or DFCS_ADJUSTRECT);
   PaintInfo.TargetCanvas.FillRect(PaintInfo.PaintRectangle);
 end;
end;

procedure Tfrm_main.vst_network_subnetdetailsAfterItemErase(
  Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode;
  ItemRect: TRect);
begin
 if Sender.Selected[Node] then
   Exit;

 if Odd(Node.Index) then
   TargetCanvas.Brush.Color := $F8F8F8
 else
   TargetCanvas.Brush.Color := clWhite;

 TargetCanvas.FillRect(ItemRect);
end;

procedure Tfrm_main.vst_network_subnetdetailsBeforeCellPaint(
  Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode;
  Column: TColumnIndex; CellPaintMode: TVTCellPaintMode; CellRect: TRect;
  var ContentRect: TRect);
var
 SubnetDetailsData : TOSubnetDetailsData;
begin
 // Spalte 0 einfärben, wenn es sich um ein Exclude handelt
 SubnetDetailsData := TOSubnetDetailsData(vst_network_subnetdetails.GetNodeData(Node)^);
 if vst_network_subnetdetails.Header.Columns[Column].Text = 'then
 begin
   if SubnetDetailsData.dhcp_exclude = 0 then
   begin
     TargetCanvas.Brush.Color := $D1D1D1;
     TargetCanvas.FillRect(CellRect);
   end;
 end;
end;

procedure Tfrm_main.vst_network_subnetdetailsCompareNodes(
  Sender: TBaseVirtualTree; Node1, Node2: PVirtualNode; Column: TColumnIndex;
  var Result: Integer);
var
 SubnetDetailsData1 : TOSubnetDetailsData;
 SubnetDetailsData2 : TOSubnetDetailsData;
begin
 SubnetDetailsData1 := TOSubnetDetailsData(vst_network_subnetdetails.GetNodeData(Node1)^);
 SubnetDetailsData2 := TOSubnetDetailsData(vst_network_subnetdetails.GetNodeData(Node2)^);
 
 if column > -1 then
 begin
   if vst_network_subnetdetails.Header.Columns[Column].Text = 'Device'        then Result := CompareStr(SubnetDetailsData1.device, SubnetDetailsData2.device);
   if vst_network_subnetdetails.Header.Columns[Column].Text = 'DHCP'          then Result := CompareStr(SubnetDetailsData1.dhcp_excludedname, SubnetDetailsData2.dhcp_excludedname);
   if vst_network_subnetdetails.Header.Columns[Column].Text = 'DHCP MAC'      then Result := CompareStr(SubnetDetailsData1.dhcp_mac, SubnetDetailsData2.dhcp_mac);
   if vst_network_subnetdetails.Header.Columns[Column].Text = 'Site'          then Result := CompareStr(SubnetDetailsData1.site, SubnetDetailsData2.site);
   if vst_network_subnetdetails.Header.Columns[Column].Text = 'Building'      then Result := CompareStr(SubnetDetailsData1.building, SubnetDetailsData2.building);
   if vst_network_subnetdetails.Header.Columns[Column].Text = 'Floor'         then Result := CompareStr(SubnetDetailsData1.floor, SubnetDetailsData2.floor);
   if vst_network_subnetdetails.Header.Columns[Column].Text = 'Position'      then Result := CompareStr(SubnetDetailsData1.position, SubnetDetailsData2.position);
   if vst_network_subnetdetails.Header.Columns[Column].Text = 'VLAN'          then Result := CompareStr(SubnetDetailsData1.vlan, SubnetDetailsData2.vlan);
   if vst_network_subnetdetails.Header.Columns[Column].Text = 'Subnet Devicethen Result := CompareStr(SubnetDetailsData1.subnetdevice, SubnetDetailsData2.subnetdevice);
   if vst_network_subnetdetails.Header.Columns[Column].Text = 'Description'   then Result := CompareStr(SubnetDetailsData1.description, SubnetDetailsData2.description);
 end;
end;

procedure Tfrm_main.vst_network_subnetdetailsFreeNode(Sender: TBaseVirtualTree;
  Node: PVirtualNode);
var
 SubnetDetailsData : TOSubnetDetailsData;
begin
 SubnetDetailsData := TOSubnetDetailsData(vst_network_subnetdetails.GetNodeData(Node)^);
 SubnetDetailsData.Free;
end;

procedure Tfrm_main.vst_network_subnetdetailsGetText(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
  var CellText: WideString);
var
 SubnetDetailsData : TOSubnetDetailsData;
begin
 SubnetDetailsData := TOSubnetDetailsData(vst_network_subnetdetails.GetNodeData(Node)^);
 if vst_network_subnetdetails.Header.Columns[Column].Text = 'IP Address'    then CellText := SubnetDetailsData.ipaddress;
 if vst_network_subnetdetails.Header.Columns[Column].Text = 'Device'        then CellText := SubnetDetailsData.device;
 if vst_network_subnetdetails.Header.Columns[Column].Text = 'DHCP'          then CellText := SubnetDetailsData.dhcp_excludedname;
 if vst_network_subnetdetails.Header.Columns[Column].Text = 'DHCP MAC'      then CellText := SubnetDetailsData.dhcp_mac;
 if vst_network_subnetdetails.Header.Columns[Column].Text = 'Site'          then CellText := SubnetDetailsData.site;
 if vst_network_subnetdetails.Header.Columns[Column].Text = 'Building'      then CellText := SubnetDetailsData.building;
 if vst_network_subnetdetails.Header.Columns[Column].Text = 'Floor'         then CellText := SubnetDetailsData.floor;
 if vst_network_subnetdetails.Header.Columns[Column].Text = 'Position'      then CellText := SubnetDetailsData.position;
 if vst_network_subnetdetails.Header.Columns[Column].Text = 'VLAN'          then CellText := SubnetDetailsData.vlan;
 if vst_network_subnetdetails.Header.Columns[Column].Text = 'Subnet Devicethen CellText := SubnetDetailsData.subnetdevice;
 if vst_network_subnetdetails.Header.Columns[Column].Text = 'Description'   then CellText := SubnetDetailsData.description;
end;

procedure Tfrm_main.vst_network_subnetdetailsHeaderClick(Sender: TVTHeader;
  Column: TColumnIndex; Button: TMouseButton; Shift: TShiftState; X,
  Y: Integer);
begin
 if Button = mbLeft then
 begin
   if Column = vst_network_subnetdetails.Header.SortColumn then
     vst_network_subnetdetails.Header.SortDirection := TSortDirection(1-ord(vst_network_subnetdetails.Header.SortDirection))
   else
     vst_network_subnetdetails.Header.SortColumn := Column;
 end;
end;

procedure Tfrm_main.vst_network_subnetdetailsHeaderDrawQueryElements(
  Sender: TVTHeader; var PaintInfo: THeaderPaintInfo;
  var Elements: THeaderPaintElements);
begin
 // Erforderlich für das Headerausehen
 Elements := [hpeBackground];
end;
Und was sagts jetzt dazu?
  Mit Zitat antworten Zitat
Benutzerbild von wicht
wicht

Registriert seit: 15. Jan 2006
Ort: Das schöne Enger nahe Bielefeld
809 Beiträge
 
Delphi XE Professional
 
#10

Re: VST mit ca. 50.000 Datensätze verdammt langsam, warum???

  Alt 7. Dez 2009, 20:52
Hast du es wenigstens mal mit Begin/EndUpdate versucht? Das würde dann so aussehen...

Delphi-Quellcode:
DSData.Open;
DSData.First;
vst_network_subnetdetails.BeginUpdate; // Neu
vst_network_subnetdetails.Clear; // Neu
for i := 0 to DSData.RecordCount - 1 do
begin
   SubnetDetailsData := TOSubnetDetailsData.Create;
   with SubnetDetailsData do
   begin
     id := DSData.FieldByName('id').AsString;
     ipaddress := DSData.FieldByName('ipaddress').AsString;
     device := DSData.FieldByName('device').AsString;
     dhcp_exclude := DSData.FieldByName('dhcp_exclude').AsInteger;
     dhcp_mac := DSData.FieldByName('dhcp_mac').AsString;
     site := DSData.FieldByName('site').AsString;
     building := DSData.FieldByName('building').AsString;
     floor := DSData.FieldByName('floor').AsString;
     position := DSData.FieldByName('position').AsString;
     vlan := DSData.FieldByName('vlan').AsString;
     subnetdevice := DSData.FieldByName('subnetdevice').AsString;
     description := DSData.FieldByName('description').AsString;
     sid := DSData.FieldByName('subnet_id').AsString;
   end;
   vst_network_subnetdetails.AddChild(nil, SubnetDetailsData);
   Application.ProcessMessages;
   DSData.Next;
end;
vst_network_subnetdetails.EndUpdate; // Neu
DSData.Close;
Ansonsten: Kommentier nach und nach deinen Code in den Ereignissen des VT aus und arbeite dich langsam vor. Dann sollte sich das Problem schnell zeigen...
http://streamwriter.org

"I make hits. Not the public. I tell the DJ’s what to play. Understand?"
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


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 22:45 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