AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi array of records mit Daten aus SQL Query füllen
Thema durchsuchen
Ansicht
Themen-Optionen

array of records mit Daten aus SQL Query füllen

Ein Thema von Gushiken · begonnen am 27. Nov 2008 · letzter Beitrag vom 27. Nov 2008
Antwort Antwort
Seite 1 von 2  1 2      
Gushiken

Registriert seit: 23. Jan 2007
12 Beiträge
 
#1

array of records mit Daten aus SQL Query füllen

  Alt 27. Nov 2008, 10:58
In einem aktuellen Programm von mir muss ich Datensätze aus einer Datenbank auslesen und in einem array of record speichern. Das funktioniert soweit auch schon ganz gut.

Sobald ich aber versuche ca. 100000 Datensätze einzulesen dauert das ganze, je nach Laune des Computers und laufenden Programmen, zwischen 4 und 8 Minuten!!!

Da das ganze beim Programmstart ausgeführt werden soll ist das untragbar, es sollte maximal 10-20 Sekunden dauern....
Hier einmal ein kleiner Beispielcode (Das Record ist eigentlich wesentlich umfangreicher):

Delphi-Quellcode:
// Record und Array of Record
TPerson = packed record
  nachname:string[50];
  end;
TPersonArray = array of TPerson;

// Funktion
with query do
begin
  with sql do
  begin
    clear;
    add('<SELECT Anweisung>');
  end;
  open;
  first;
  len:=RecordCount;
  setLength(personenArray,len);
  len:=0;
  while len<RecordCount do
  begin
    with personenArray[len] do
    begin
      nachname:=Fields.Fields[0].AsString;
    end;
    next;
    len:= len+1;
  end;
end;
Vielleicht habt ihr ja eine Idee wie man das ganze schneller machen kann.

Gruß, Gushiken
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.540 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: array of records mit Daten aus SQL Query füllen

  Alt 27. Nov 2008, 11:09
Ist es wirklich notwendig, beim Programmstart 100000 Datensätze einzulesen? An Deinem Code sehe ich nicht viele Optimierungsmöglichkeiten (vielleicht mal das "packed" weglassen).
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von dataspider
dataspider

Registriert seit: 9. Nov 2003
Ort: 04539 Groitzsch
1.350 Beiträge
 
Delphi 11 Alexandria
 
#3

Re: array of records mit Daten aus SQL Query füllen

  Alt 27. Nov 2008, 11:14
Vielleicht bringt Unidirectional := True noch etwas.

Frank
Frank Reim
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#4

Re: array of records mit Daten aus SQL Query füllen

  Alt 27. Nov 2008, 11:55
Hallo,

je nach Datenbank kann ein len:=RecordCount lange dauern, da zuweilen die Datensätze wirklich gezählt werden, d.h. die Datenmenge wird einmal durchlaufen (egal ob auf dem Client oder dem Server). Einige Datenbanken liefern die ersten Sätze der Ergebnismenge ja schon aus, bevor das gesamte Ergebnis der Abfrage feststeht, d. h.: Du liest die ersten Daten schon, während die Datenbank noch mit dem Ermitteln der Ergebnismenge beschäftigt ist. Möchtest Du nun wissen, mit wievielen Sätzen Du zu rechnen hast, muss die Datenbank die Ergebnismenge vollständig "zusammen" haben.
Ob's bei Dir so ist, kann ich nicht sagen.

Versuche mal vorher ein Select Count(*) entsprechend Deinem Select zu machen und nehme für len diesen Wert, statt RecordCount.

Der Record besteht sicherlich nicht nur aus nachname. Wieviel Byte an Daten hat ein Record, wieviel gibt das mal 100000? Reicht der Arbeitsspeicher oder muss ausgelagert werden. Dann wird es immer deutlich langsamer. Wenn's wirklich an der Laune des Computers und der laufenden Programme liegt, dann sorg' mal für mehr Arbeitsspeicher. Schau Dir im Taskmanager mal die "Speicherentwicklung" beim Programmstart an und eventuell auch mal die Grafiken über CPU-Belastung und Speichernutzung.

Warum so?
Delphi-Quellcode:
  len:=0;
  while len<RecordCount do
  begin
    with personenArray[len] do
    begin
      nachname:=Fields.Fields[0].AsString;
    end;
    next;
    len:= len+1;
  end;
Wäre eventuell auch
Delphi-Quellcode:
  first;
  len:=0;
  while not EoF do
  begin
    with personenArray[len] do
    begin
      nachname:=Fields.Fields[0].AsString;
    end;
    next;
    len:= len+1;
  end;
möglich?
Ich weiß nicht, wie RecordCount intern funktioniert, ob es wirklich nur ein Wert ist, der einmalig zugewiesen wird oder eine Funktion im Getter, die bei jedem Zugriff die Anzahl der Datensätze ermittelt. Eine Alternative könnte also sein:
Delphi-Quellcode:
// Funktion
with query do
begin
  with sql do
  begin
    clear;
    add('<SELECT Anweisung>');
  end;
  open;
  // first; // bei open sollte man schon auf dem ersten Satz stehen.
  satzzahl := RecordCount;
  setLength(personenArray,satzzahl);
  len:=0;
  while len < satzzahl do
  begin
    with personenArray[len] do
    begin
      nachname:=Fields.Fields[0].AsString;
    end;
    next;
    Inc(len);
  end;
end;
  Mit Zitat antworten Zitat
Gushiken

Registriert seit: 23. Jan 2007
12 Beiträge
 
#5

Re: array of records mit Daten aus SQL Query füllen

  Alt 27. Nov 2008, 12:22
Danke schonmal für die schnellen Antworten!!

Zitat:
Der Record besteht sicherlich nicht nur aus nachname. Wieviel Byte an Daten hat ein Record, wieviel gibt das mal 100000? Reicht der Arbeitsspeicher oder muss ausgelagert werden. Dann wird es immer deutlich langsamer. Wenn's wirklich an der Laune des Computers und der laufenden Programme liegt, dann sorg' mal für mehr Arbeitsspeicher. Schau Dir im Taskmanager mal die "Speicherentwicklung" beim Programmstart an und eventuell auch mal die Grafiken über CPU-Belastung und Speichernutzung.
Zur Speicherauslastung kann ich folgendes sagen:
- Beim Programmstart liegt die Auslastung bei ca 4.000K
- Nach der Abfrage von den 100.000 Datensätzen geht die Auslastung hoch auf ca. 40.000K
- Nach erfolgreichem erstellen des Arrays liegt das ganze bei ca 45.000K
- Nach befüllen eines Grids mit den Daten geht das ganze hoch auf 128.000K

Selbst nachdem das Grid befüllt ist sollte das ganze für meinen PC, der relativ lahm ist und 1GB RAM hat, kein Problem darstellen.

Die Zeit die RecordCount benötigt müsste ich mal testen... Das könnte sicherlich eine Bremse sein wenn der Wert jedesmal neu erzeugt wird, was ich mir aber eigentlich nicht vorstellen kann. Aber ich werde das mal testen und das Ergebnis posten.

Die Variante mit EOF hatte ich bereits einmal implementiert, das ganze aber verworfen.. aber mir fällt der Grund gerade nicht ein... Aber es war nicht wirklich performanter.

Die 100.000 Datensätze einzulesen ist nötig um bei einer Suche nach einer Person nicht jedes mal wieder eine SQL Abfrage starten zu müssen. Die Suche im Array geht wesentlich schneller als die Suche in der DB per SQL. (Eine Suche nach 3 Buchstaben innerhalb eines Namens dauert bei 100.000 Datensätzen im Array mit Ausgabe im Grid ca 50ms)
  Mit Zitat antworten Zitat
Hansa

Registriert seit: 9. Jun 2002
Ort: Saarland
7.554 Beiträge
 
Delphi 8 Professional
 
#6

Re: array of records mit Daten aus SQL Query füllen

  Alt 27. Nov 2008, 12:28
Ist das Grid beim Befüllen sichtbar ? Falls ja, dann würde mich ein Faktor von 10-100 niccht wundern.
Gruß
Hansa
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.540 Beiträge
 
Delphi 11 Alexandria
 
#7

Re: array of records mit Daten aus SQL Query füllen

  Alt 27. Nov 2008, 12:30
Grid? Womöglich TStringGrid? Dann solltest Du mal ein Beginupdate und ein Endupdate einfügen, da hier vermutlich die Bremse liegt, wie Hansa so treffend meint.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von gsh
gsh

Registriert seit: 24. Okt 2004
1.542 Beiträge
 
Delphi XE Architect
 
#8

Re: array of records mit Daten aus SQL Query füllen

  Alt 27. Nov 2008, 12:41
Zitat von Gushiken:
Die 100.000 Datensätze einzulesen ist nötig um bei einer Suche nach einer Person nicht jedes mal wieder eine SQL Abfrage starten zu müssen. Die Suche im Array geht wesentlich schneller als die Suche in der DB per SQL. (Eine Suche nach 3 Buchstaben innerhalb eines Namens dauert bei 100.000 Datensätzen im Array mit Ausgabe im Grid ca 50ms)
hmm imho ist eine datenbank eigentlich für genau solche abfragen da.
Außerdem glaube ich (Bei einem richtigen SQL Server) ist die Suche in der DB auf jedenfall schneller.
Also bei meiner MySQL Datenbank brauch ich für eine Vergleichbare Abfrage circa 3 ms.
Alex
"Sage nicht alles, was du weißt, aber wisse alles, was du sagst!" Matthias Claudius
"Wer sich über Kritik ärgert, gibt zu, daß er sie verdient hat." Tacitus
  Mit Zitat antworten Zitat
Gushiken

Registriert seit: 23. Jan 2007
12 Beiträge
 
#9

Re: array of records mit Daten aus SQL Query füllen

  Alt 27. Nov 2008, 12:52
Das Grid bremst das ganze zwar schon deutlich, etwas über eine Minute, aber auch ohne die Visualisierung im Grid bemötige ich noch durchschnittlich 3-4 Minuten.
Das Grid wird im übrigen auch später nicht mehr benötigt. Es geht hauptsächlich um die Erstellung des Arrays.



Zitat von gsh:
Zitat von Gushiken:
Die 100.000 Datensätze einzulesen ist nötig um bei einer Suche nach einer Person nicht jedes mal wieder eine SQL Abfrage starten zu müssen. Die Suche im Array geht wesentlich schneller als die Suche in der DB per SQL. (Eine Suche nach 3 Buchstaben innerhalb eines Namens dauert bei 100.000 Datensätzen im Array mit Ausgabe im Grid ca 50ms)
hmm imho ist eine datenbank eigentlich für genau solche abfragen da.
Außerdem glaube ich (Bei einem richtigen SQL Server) ist die Suche in der DB auf jedenfall schneller.
Also bei meiner MySQL Datenbank brauch ich für eine Vergleichbare Abfrage circa 3 ms.

Die Abfrage an sich ist schneller. Allerdings muss man die Daten erstmal zur Datenbank hinbekommen, zurückholen und verarbeiten. Ich habs zwar selbst nicht getestet, aber meinem Ausbilder (ja, ich bin noch ein FIT in der Ausbildung *schäm*) meinte das eine Personensuche bei einer Tabelle mit ca 100.000 Datensätzen schnell 20s dauert, inkl. Verarbeitung und Anzeige im Grid.
Zudem verwenden wir einen MSSQL Server der, soweit ich weiß, ne ganze Ecke langsamer ist als MySQL.

Aber wie groß war die Datenbank denn wenn die Abfrage bloß 3ms dauert?? Und hattest du LEFT JOIN's in der Abfrage? Hier mal die 'echte' SQL Abfrage:
Delphi-Quellcode:
query.sql.add('SELECT '+
        ' p.name,'+
        ' p.vorname,'+
        ' p.id,'+
        ' s.bezeichnung as strasse,'+
        ' p.hausnr,'+
        ' o.bezeichnung as ort,'+
        ' o.plz as plz,'+
        ' day(p.geburtsdatum) as tag,'+
        ' month(p.geburtsdatum) as monat,'+
        ' year(p.geburtsdatum) as jahr,'+
        ' p.debitoren_nr as personenktonr'+
        ' FROM personen as p'+
        ' LEFT JOIN strassen as s ON s.id = p.strassen_id'+
        ' LEFT JOIN orte as o ON o.id = p.orte_id'+
        ' WHERE p.sys_delete = '+QuotedStr('F')+
        ' ORDER BY name');
  Mit Zitat antworten Zitat
Benutzerbild von Jelly
Jelly

Registriert seit: 11. Apr 2003
Ort: Moestroff (Luxemburg)
3.741 Beiträge
 
Delphi 2007 Professional
 
#10

Re: array of records mit Daten aus SQL Query füllen

  Alt 27. Nov 2008, 13:01
Ich komm nochmals auf die Ausgangsfrage zurück: Ist es wirklich notwendig 100000 Datensätze lokal auf den Client zu laden. Was machst du damit? Kein Benutzer wird 100000 Datensätze in einem Grid durchscrollen, ohne nach einer Suchfunktion zu schreien.
  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 03:54 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