AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Viele Datensätze nacheinander erstellen
Thema durchsuchen
Ansicht
Themen-Optionen

Viele Datensätze nacheinander erstellen

Ein Thema von Reinhardtinho · begonnen am 22. Jan 2008 · letzter Beitrag vom 25. Jan 2008
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Reinhardtinho
Reinhardtinho

Registriert seit: 26. Feb 2007
411 Beiträge
 
Delphi 5 Enterprise
 
#1

Viele Datensätze nacheinander erstellen

  Alt 22. Jan 2008, 14:02
Datenbank: SQL Server 2000 • Zugriff über: SDAC-Komponenten
Hi,

ich habe mir ein kleines Musik-Verwaltungstool gebastelt, dass die Dateien in einem Ordner sucht und die Informationen in einem neuen Datensatz in einer Datenbank speichert (Name, Pfad, einige ID3-Tags, ggf. Cover).

Wenn ich die Suche starte, läuft das Programm noch sehr schnell, es werden so ca. 20-40 Datensätze pro Sekunde eingefügt.

Doch ab 5000 etwa wird es sehr langsam und am Ende braucht das Tool 1-2 Sekunden pro Datensatz. Das Taskmanager zeigt an, dass der Prozess sqlservr.exe einen virtuellen Speicher von etwa 500.000k hat.

Ich hab es auf meinem Laptop (WinXP - SP2, 2 GHz, 512 MB Ram) laufen.

Hier nochmal kurz der Code, wie ich die Datensätze erstelle, der immer aufgerufen wird, wenn das Programm eine mp3-Datei gefunden hat.

Delphi-Quellcode:
  try
    if MSTable_Wrk.Locate('Pfad', FileName, [loCaseInsensitive]) then
    begin
      MSTable_Wrk.Edit;
      Inc(ChangedFiles);
    end
    else
    begin
      MSTable_Wrk.Append;
      Inc(NewFiles);
    end;

    if Assigned(OnTTDProgress) then
      OnTTDProgress(self, NewFiles, ChangedFiles);

    with MSTable_Wrk do
    begin
      FieldValues['Pfad'] := FileName;
      FieldValues['Name'] := StringReplace(ExtractFileName(FileName), ExtractFileExt(FileName), '', []);
      FieldValues['Ordner'] := ExtractFilePath(FileName);

      FTyp := LowerCase(ExtractFileExt(FileName));

      if (Pos('.', FTyp) > 0) then
        FTyp := Copy(FTyp, 2, Length(FTyp) - 1);

      FieldValues['Typ'] := FTyp;

      FGroesse := FormatFloat('0 B', Dateigroesse);

      if (Dateigroesse DIV 1024 > 0) then
        FGroesse := FormatFloat('#,##0.00 KB', Dateigroesse / 1024);

      if (Dateigroesse DIV 1048576 > 0) then
        FGroesse := FormatFloat('#,##0.00 MB', Dateigroesse / 1048576);

      if (Dateigroesse DIV 1073741824 > 0) then
        FGroesse := FormatFloat('#,##0.00 GB', Dateigroesse / 1073741824);

      if ((Dauer MOD 60) > 9) then
        FDauer := IntToStr(Dauer DIV 60) + ':' + IntToStr(Dauer MOD 60)
      else FDauer := IntToStr(Dauer DIV 60) + ':0' + IntToStr(Dauer MOD 60);

      FieldValues['Groesse'] := FGroesse;
      FieldValues['Interpret'] := Artist;
      FieldValues['Titel'] := Titel;
      FieldValues['Album'] := Album;
      FieldValues['Jahr'] := Year;
      FieldValues['Genre'] := Genre;
      FieldValues['Lyrics'] := Lyrics;
      FieldValues['Dauer'] := FDauer;
      FieldValues['Bitrate'] := Bitrate;
      FieldValues['Vbr'] := Vbr;
      FieldValues['ChannelMode'] := ChannelMode;
      FieldValues['Samplerate'] := Samplerate;
      FieldValues['Schreibgeschuetzt'] := FReadOnly;
      FieldValues['Versteckt'] := FHidden;
      FieldValues['Erstelldatum'] := Created;
      JvDBImage1.Picture.Assign(JvID3v21.Images.Pictures.CoverFront);

      Post;
    end; (* of with *)

    JvID3v21.Active := False;
  except
    //
  end;
Gibt es eine Möglichkeit die Suche + Erstellung der Datensätze dauerhaft mit der Geschwindigkeit wie zu Beginn auszuführen?


P.S.: Die MSTable_Wrk-Komponente ist nicht mit einer visuellen Komponente verknüpft.


Vielen Dank und freundliche Grüße
Lorenz
Ich habe viel von meinem Geld für Alkohol, Weiber und schnelle Autos ausgegeben ... Den Rest habe ich einfach verpraßt.

George Best - 22.05.1946 - 25.11.2005 - nordirischer Fußballspieler
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.492 Beiträge
 
Delphi 7 Enterprise
 
#2

Re: Viele Datensätze nacheinander erstellen

  Alt 22. Jan 2008, 14:06
Du solltest einen Index auf Deinen Suchbegriff aufbauen ( in dem Fall auf FileName)
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  Mit Zitat antworten Zitat
Benutzerbild von RavenIV
RavenIV

Registriert seit: 12. Jan 2005
Ort: Waldshut-Tiengen
2.875 Beiträge
 
Delphi 2007 Enterprise
 
#3

Re: Viele Datensätze nacheinander erstellen

  Alt 22. Jan 2008, 14:12
Das Einfügen in die DB dauert wohl am längsten bei dem Programm, bzw. frisst die meiste Zeit.

Warum benutzt Du nicht eine Liste als Zwischenspeicher und fügst alle Datensätze in einem Rutsch in die DB ein?
Es würde sich ein Record und eine Liste von Records anbieten.
Klaus E.
Linux - das längste Text-Adventure aller Zeiten...
Wer nie Linux mit dem vi konfiguriert hat, der hat am Leben vorbei geklickt.
  Mit Zitat antworten Zitat
Benutzerbild von mschaefer
mschaefer

Registriert seit: 4. Feb 2003
Ort: Hannover
2.032 Beiträge
 
Delphi 12 Athens
 
#4

Re: Viele Datensätze nacheinander erstellen

  Alt 22. Jan 2008, 14:24
Moin, moin,

Du rufst Deine Routine mehrmals auf. Nimm das Post aus der Routine selbst und setzte es hinter Deine aufrufende Schleife.
Damit werden alle Datensätze aufeinmal in die DB geschrieben.

Grüße // Martin
Martin Schaefer
Phaeno
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.197 Beiträge
 
Delphi 10.4 Sydney
 
#5

Re: Viele Datensätze nacheinander erstellen

  Alt 22. Jan 2008, 14:33
Prepared parametrisierte Abfragen ist das Zauberwort um den Import zu beschleunigen.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Benutzerbild von Reinhardtinho
Reinhardtinho

Registriert seit: 26. Feb 2007
411 Beiträge
 
Delphi 5 Enterprise
 
#6

Re: Viele Datensätze nacheinander erstellen

  Alt 22. Jan 2008, 14:35
Hi,

danke euch schon mal für die schnellen Antworten, ich kann es leider erst heute abend testen.

Einen Index werde ich noch auf FileName setzen.

Ist es für den Arbeitsspeicher besser, wenn ich die Daten alle erst am Ende in die DB speichere oder soll ich ca. alle 500 Dateien ein Post absetzen?


MFG
Lorenz
Ich habe viel von meinem Geld für Alkohol, Weiber und schnelle Autos ausgegeben ... Den Rest habe ich einfach verpraßt.

George Best - 22.05.1946 - 25.11.2005 - nordirischer Fußballspieler
  Mit Zitat antworten Zitat
hoika

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

Re: Viele Datensätze nacheinander erstellen

  Alt 22. Jan 2008, 15:08
Hallo,

viell. liegt es auch an der Komponente.
Du benutzt eine Table, beim SQL-Server wäre aber eien Query
mit prepared statements besser.

Ausserdem erteugst du mit deinem aktuellen Code
bei jedem Post ein Transaktion.Commit (oder wie Connection.Commit).

Ich würde vor dem ersten Schleife ein StartTransaction
und danach ein Commit absetzen.


Heiko
Heiko
  Mit Zitat antworten Zitat
tomsson74

Registriert seit: 8. Jan 2008
73 Beiträge
 
Turbo Delphi für Win32
 
#8

Re: Viele Datensätze nacheinander erstellen

  Alt 23. Jan 2008, 00:26
Zitat von Reinhardtinho:
Delphi-Quellcode:
    with MSTable_Wrk do
    begin
      FieldValues['Pfad'] := FileName;
      FieldValues['Name'] := StringReplace(ExtractFileName(FileName), ExtractFileExt(FileName), '', []);
      FieldValues['Ordner'] := ExtractFilePath(FileName);
      FieldValues['Groesse'] := FGroesse;
      FieldValues['Interpret'] := Artist;
      FieldValues['Titel'] := Titel;
      FieldValues['Album'] := Album;
      FieldValues['Jahr'] := Year;
      FieldValues['Genre'] := Genre;
      FieldValues['Lyrics'] := Lyrics;
      FieldValues['Dauer'] := FDauer;
      FieldValues['Bitrate'] := Bitrate;
      FieldValues['Vbr'] := Vbr;
      FieldValues['ChannelMode'] := ChannelMode;
      FieldValues['Samplerate'] := Samplerate;
      FieldValues['Schreibgeschuetzt'] := FReadOnly;
      FieldValues['Versteckt'] := FHidden;
      FieldValues['Erstelldatum'] := Created;
      JvDBImage1.Picture.Assign(JvID3v21.Images.Pictures.CoverFront);
Diese Zuweisungen wirken sich auch auf die Performance des Programms aus - obgleich das wahrscheinlin nicht die Hauptursache für Dein Problem ist. Die Eigenschaft FieldValues arbeitet mit dem Datentyp 'Variant' so dass der Datenzugriff im Vergleich zu nativen Datentypen langsamer erfolgt.

Persönlich würde ich daher die andere Schreibweise empfehlen, z.B so ...

Delphi-Quellcode:
      (...)
      FieldByName('Groesse').AsInteger := FGroesse;
      FieldByName('Interpret').AsString := Artist;
      FieldByName('Titel').AsString := Titel;
      (...)
      FieldByName('Jahr').AsInteger := Year;
usw.

/Thomas
  Mit Zitat antworten Zitat
grenzgaenger
(Gast)

n/a Beiträge
 
#9

Re: Viele Datensätze nacheinander erstellen

  Alt 23. Jan 2008, 00:32
das mag zwar sein, aber der aufwand ist linear. wenn die zeit der operationen nach oben geschraubt wird, gibt es hierfür zwei möglichkeiten
  • dein SQL statement und tabellendefinition ist nicht dafür vorgesehen und somit unperformant
  • du hast noch irgendwelche algos und programmcode, der mit der anzahl der datensetze und/oder der laufzeit ein ziemlich krankes verhalten zeigt

im zweiten fall, poste doch mal deine prozeduren/funktionen die beim einlesen mit durchlaufen werden...
  Mit Zitat antworten Zitat
Benutzerbild von Reinhardtinho
Reinhardtinho

Registriert seit: 26. Feb 2007
411 Beiträge
 
Delphi 5 Enterprise
 
#10

Re: Viele Datensätze nacheinander erstellen

  Alt 24. Jan 2008, 09:55
Hi,

vielen Dank für eure Antworten.

Neben dem oben im ersten Post genannten Code, der immer aufgerufen wird, wenn ich eine Datei gefunden habe, mache ich noch folgendes:

[Edit]Aber die DataSource-Komponente ist mit der MStable1 und nicht mit der Working-Table verknüpft, die ich ja fülle.[/Edit]

Delphi-Quellcode:
procedure TForm_Main.DataSource1DataChange(Sender: TObject; Field: TField);
begin
  Label1.Caption := 'Datensatz: ' + IntToStr(MSTable1.RecNo) + '/' + IntToStr(MSTable1.RecordCount);

  if MSTable1.Active then
  begin
    if (MSTable1.RecordCount > 0) then
    begin
      BitBtn_Datei.Enabled := True;
      Datei2.Enabled := True;
    end
    else
    begin
      BitBtn_Datei.Enabled := False;
      Datei2.Enabled := False;
    end;

    BitBtn_Ordner.Enabled := True;
    BitBtn_Suche.Enabled := True;
    BitBtn_Backup.Enabled := True;
    BitBtn_Import.Enabled := True;
    BitBtn_Export.Enabled := True;

    Ordner1.Enabled := True;
    Suche1.Enabled := True;
    Import1.Enabled := True;
    Export1.Enabled := True;
    BackupRestore1.Enabled := True;

    ComboBox1.Enabled := True;
  end
  else
  begin
    BitBtn_Ordner.Enabled := False;
    BitBtn_Suche.Enabled := False;
    BitBtn_Backup.Enabled := False;
    BitBtn_Import.Enabled := False;
    BitBtn_Export.Enabled := False;

    Ordner1.Enabled := False;
    Suche1.Enabled := False;
    Import1.Enabled := False;
    Export1.Enabled := False;
    BackupRestore1.Enabled := False;

    ComboBox1.Enabled := False;
  end;
end;


Ich habe das "Post" nach dem kompletten Suchvorgang erst gesetzt, aber das Phänomen bleibt das selbe. Auch der Arbeitsspeicher wird wieder hoch ausgelastest (Prozess: sqlservr.exe).


Ich habe auch das mit dem .AsString probiert, aber ich erhalte da folgende Fehlermeldung:
"Variante referenziert kein Automatisierungsobjekt. (EOleError).


Es kann ja eigentlich nicht sein, dass bei einer Anzahl von 5000 Datensätzen die Auslagerungsdatei des Sql-Servers bei 300 MB liegt, oder?
Ich denke, daran liegt es auch, dass die Performance so drastisch nachlässt.



MFG
Lorenz
Ich habe viel von meinem Geld für Alkohol, Weiber und schnelle Autos ausgegeben ... Den Rest habe ich einfach verpraßt.

George Best - 22.05.1946 - 25.11.2005 - nordirischer Fußballspieler
  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 00:34 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