RAM verbrauchsproblem Postgresql+ZEOS
-
- Beiträge: 162
- Registriert: Mi 31. Jul 2013, 15:07
- OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80
Re: RAM verbrauchsproblem Postgresql+ZEOS
af0815: ich habe auch mit mehr daten probiert und wenn dann der verbrauch zumbeispiel bei 25MB text auf 1-1.5GB steigt wird das schonmal problematisch bei 4GB ram
- af0815
- Lazarusforum e. V.
- Beiträge: 6198
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: RAM verbrauchsproblem Postgresql+ZEOS
Ok, wenn so zunimmt schon
Kann man das Problem in eine Beispielprojekt stecken ? Ich sehe mir es gerne mal an (mit sqlite), klingt irgendwie interessant.
Andreas
Kann man das Problem in eine Beispielprojekt stecken ? Ich sehe mir es gerne mal an (mit sqlite), klingt irgendwie interessant.
Andreas
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
Re: RAM verbrauchsproblem Postgresql+ZEOS
Was passiert eigentlich sonst noch in der Anwendung? Wir hatten hier immer wieder den Fall, dass harmloser Code gezeigt wurde, aber Hund ganz wo anders begraben war.
-
- Beiträge: 162
- Registriert: Mi 31. Jul 2013, 15:07
- OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80
Re: RAM verbrauchsproblem Postgresql+ZEOS
ich habe den gesamten code eine seite vorher gepostet den SQLite code den ich benutzt habe.
Habe wies da steht die Lazaruskomponente verwendet nicht ZEOS , ZEOS hatte ich nur bei den POstgresql tests verwendet
aber hier nochmal der aktuelle code aber kein ZEOS benutzt wie gesagt
sonst passiert nix mehr habe nur zwei buttons einmal der SQLite testcode einmal der Postgresql code weil ich zum ersten mal eine Datenbankanbindung baue
Habe wies da steht die Lazaruskomponente verwendet nicht ZEOS , ZEOS hatte ich nur bei den POstgresql tests verwendet
aber hier nochmal der aktuelle code aber kein ZEOS benutzt wie gesagt
Code: Alles auswählen
procedure TForm1.Button1Click(Sender: TObject);
var
i: qword;
Origin: string;
sl: TStringList;
begin
SQLite3Connection1.DatabaseName := './DB.sqlite';
SQLTransaction1.Database := SQLite3Connection1;
SQLite3Connection1.Open;
if SQLite3Connection1.Connected then
Form1.Caption := 'Verbindung hergestellt';
SQLQuery1.Transaction := SQLTransaction1;
//Erzeugt Wörterbuchliste
SQLQuery1.SQL.Text := 'CREATE TABLE IF NOT EXISTS tblDictonary (ID INTEGER Primary KEY, Wort VARCHAR(255) UNIQUE ON CONFLICT IGNORE);';
SQLQuery1.ExecSQL;
SQLTransaction1.commit;
Origin := Loadfile('./test');
Origin := Stringreplace(Origin, '"', '', [rfReplaceAll]);
sl := TStringList.Create;
sl.Delimiter := ' ';
sl.QuoteChar := #$0;
sl.DelimitedText := Origin;
SQLQUERY1.Close;
for i := 0 to sl.Count - 1 do
begin
SQLQuery1.SQL.Text := 'INSERT INTO tblDictonary (Wort) VALUES ("' + sl[i] + '")';
SqlQuery1.ExecSQL;
//SqlTransaction1.Commit;
if i mod 1000 = 0 then
begin
SqlTransaction1.Commit;
Form1.Caption := IntToStr(i);
end;
end;
SQLQuery1.Close;
end;
sonst passiert nix mehr habe nur zwei buttons einmal der SQLite testcode einmal der Postgresql code weil ich zum ersten mal eine Datenbankanbindung baue
- af0815
- Lazarusforum e. V.
- Beiträge: 6198
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: RAM verbrauchsproblem Postgresql+ZEOS
Wie groß sind die Strings die du da einliest, bzw wie sehen die Strings in etwa aus.
Wenn dein Code so einfach ist, dann hätte ich ihn mit den Beispieldaten gezippt und hier hochgeladen
Wenn dein Code so einfach ist, dann hätte ich ihn mit den Beispieldaten gezippt und hier hochgeladen
Zuletzt geändert von af0815 am Sa 29. Okt 2016, 20:42, insgesamt 1-mal geändert.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
-
- Beiträge: 162
- Registriert: Mi 31. Jul 2013, 15:07
- OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80
Re: RAM verbrauchsproblem Postgresql+ZEOS
der inputstring ist einfach eine textdatei die textdatei (die kleine) die ich zum testen genommen habe hatte ich verlinkt eine seite vorher. Die große ist auch einfach ein standarttext einfach nur größer ca 25MB
- af0815
- Lazarusforum e. V.
- Beiträge: 6198
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: RAM verbrauchsproblem Postgresql+ZEOS
Kannst du sagen wie lange in Zeichen die einzelnen Strings sind. Kannst ja notfalls ein Paar hier als Beispiel posten
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
-
- Beiträge: 162
- Registriert: Mi 31. Jul 2013, 15:07
- OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80
Re: RAM verbrauchsproblem Postgresql+ZEOS
ich schmeiß einfach ein text rein und delimite bei jedem space und lese die wörter anschliesend wie zu sehen eins nach dem anderen ein um so ein wörterbuch zu erhalten
- af0815
- Lazarusforum e. V.
- Beiträge: 6198
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: RAM verbrauchsproblem Postgresql+ZEOS
Ok, hab den Text jetzt gefunden, beim Scollen überlesen. Baue mir mal ein Programm dazu. Aktuell unter Windows 10, weil ich gerade auf der Maschine arbeite.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
-
- Beiträge: 162
- Registriert: Mi 31. Jul 2013, 15:07
- OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80
Re: RAM verbrauchsproblem Postgresql+ZEOS
Mit dem kleinen testtext hatte ich 75MB ram verbrauch explodieren tut er erst später bei größerem input.
Und nach dem freigeben immernoch 40MB
vor dem start der befüllung ca 13MB
Und nach dem freigeben immernoch 40MB
vor dem start der befüllung ca 13MB
- af0815
- Lazarusforum e. V.
- Beiträge: 6198
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: RAM verbrauchsproblem Postgresql+ZEOS
So wie ich es mir gedacht habe, du hast noch ander Funktionen benutzt
wo ist die Loadfile('./test') ?
Das ist genau der Grund warum nach einem KOMPLETTEN Beispielcode verlangt wird - damit der Code vollständig ist und man nicht unnötig hersuchen und schreiben muss, wenn man sich schon ein Problem von wem ansehen will/möchte.
wo ist die Loadfile('./test') ?
Das ist genau der Grund warum nach einem KOMPLETTEN Beispielcode verlangt wird - damit der Code vollständig ist und man nicht unnötig hersuchen und schreiben muss, wenn man sich schon ein Problem von wem ansehen will/möchte.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
-
- Beiträge: 162
- Registriert: Mi 31. Jul 2013, 15:07
- OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80
Re: RAM verbrauchsproblem Postgresql+ZEOS
komplett
Code: Alles auswählen
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, sqldb, DB, sqlite3conn, FileUtil, ZConnection, ZDataset,
Forms, Controls, Graphics, Dialogs, StdCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
DataSource1: TDataSource;
ListBox1: TListBox;
SQLite3Connection1: TSQLite3Connection;
SQLQuery1: TSQLQuery;
SQLTransaction1: TSQLTransaction;
ZConnection1: TZConnection;
ZQuery1: TZQuery;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
//Quelle entwicklerecke
function LoadFile(FilePath: string): string;
var
fm: tfilestream;
s: string;
begin
fm := tfilestream.Create(FilePath, fmopenread);
setlength(s, fm.size);
fm.Read(s[1], fm.size);
fm.Free;
Result := s;
s := '';
end;
//----
{$R *.lfm}
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
var
i: qword;
Origin: string;
sl: TStringList;
begin
SQLite3Connection1.DatabaseName := './DB.sqlite';
SQLTransaction1.Database := SQLite3Connection1;
SQLite3Connection1.Open;
if SQLite3Connection1.Connected then
Form1.Caption := 'Verbindung hergestellt';
SQLQuery1.Transaction := SQLTransaction1;
//Erzeugt Wörterbuchliste
SQLQuery1.SQL.Text := 'CREATE TABLE IF NOT EXISTS tblDictonary (ID INTEGER Primary KEY, Wort VARCHAR(512) UNIQUE ON CONFLICT IGNORE);';
SQLQuery1.ExecSQL;
SQLTransaction1.commit;
Origin := Loadfile('./White_Fang');
Origin := Stringreplace(Origin, '"', '', [rfReplaceAll]);
sl := TStringList.Create;
sl.Delimiter := ' '; // Leerzeichen als Wort Trenner
sl.QuoteChar := #$0; // keine " als Maskierung
sl.DelimitedText := Origin;
//Daten in Wörterbuch eintrag
SQLQUERY1.Close;
for i := 0 to sl.Count - 1 do
begin
SQLQuery1.SQL.Text := 'INSERT INTO tblDictonary (Wort) VALUES ("' + sl[i] + '")';
SqlQuery1.ExecSQL;
if i mod 1500 = 0 then
begin
SqlTransaction1.Commit;
SQLQuery1.Clear;
Form1.Caption := IntToStr(i);
end;
end;
SQLite3Connection1.Free;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
i: qword;
Origin: string;
sl: TStringList;
begin
ZQuery1.Close();
ZQuery1.SQL.Clear;
try
ZQuery1.SQL.Add('SELECT * FROM dict LIMIT 1;');
except
ZQuery1.SQL.Add('CREATE TABLE IF NOT EXISTS dict ( id SERIAL PRIMARY KEY , word varchar(512) NOT NULL);');
ZQuery1.SQL.Add(
'CREATE TABLE IF NOT EXISTS stats ( w1 INTEGER NOT NULL REFERENCES dict(id), w2 INTEGER NOT NULL REFERENCES dict(id), fw INTEGER NOT NULL REFERENCES dict(id), az INTEGER NOT NULL, PRIMARY KEY (w1, w2, fw));');
ZQuery1.SQL.Add('CREATE UNIQUE INDEX ON dict(word);');
end;
ZQuery1.Open;
ZQuery1.ExecSQL;
Origin := Loadfile('./White_Fang');
Origin := Stringreplace(Origin, '''', '''' + '''', [rfReplaceAll]);
sl := TStringList.Create;
sl.Delimiter := ' ';
sl.QuoteChar := #$0;
sl.DelimitedText := Origin;
for i := 0 to sl.Count - 1 do
begin
//ZQuery1.SQL.Clear;
//ZQuery1.SQL.Add('INSERT INTO dict (word) VALUES (''' + sl[i] + ''') ON CONFLICT DO NOTHING;');
//ZQuery1.ExecSQL;
ZQuery1.SQL.Text := 'INSERT INTO dict (word) VALUES (''' + sl[i] + ''') ON CONFLICT DO NOTHING;';
ZQuery1.ExecSQL;
if i mod 1000 = 0 then
begin
ZConnection1.Commit;
Form1.Caption := IntToStr(i);
end;
end;
sl.Free;
end;
end.
- af0815
- Lazarusforum e. V.
- Beiträge: 6198
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: RAM verbrauchsproblem Postgresql+ZEOS
Geht so schneller mit sqlite
Code: Alles auswählen
Origin := Loadfile('./test.txt');
Origin := Stringreplace(Origin, '"', '', [rfReplaceAll]);
sl := TStringList.Create;
sl.Delimiter := ' ';
sl.QuoteChar := #$0;
sl.DelimitedText := Origin;
SQLQuery1.Close;
SQLQuery1.Params.Clear;
SQLQuery1.SQL.Text := 'INSERT INTO tblDictonary (Wort) VALUES (:sWort)';
SQLQuery1.Prepare;
for i := 0 to sl.Count - 1 do
begin
SQLQuery1.ParamByName('sWort').AsString:= sl[i];
SqlQuery1.ExecSQL;
//SqlTransaction1.Commit;
if i mod 1000 = 0 then
begin
SqlTransaction1.Commit;
Form1.Caption := IntToStr(i);
end;
end;
SQLQuery1.Close;
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
-
- Beiträge: 162
- Registriert: Mi 31. Jul 2013, 15:07
- OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80
Re: RAM verbrauchsproblem Postgresql+ZEOS
af0815: danke
- af0815
- Lazarusforum e. V.
- Beiträge: 6198
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: RAM verbrauchsproblem Postgresql+ZEOS
Die Stringlist wird auch nicht freigegeben
und das ist IMHO auch sicherer
Edit: Das sl.free hat nur bei der sqlite Variante gefehlt. Das mit den Parametern und dem Prepare kann drastische geschwindigkeits vorteile bringen, da der sog. Ausführungsplan nicht neu erstellt werden muß. Wenn du jedesmal das SQL-Statement angibst, so wird auch in den SQL-DB Komponenten das ganze Statement neu verarbeitet, die Strukturen verworfen und neu erstellt und dann dem Server die Änderungen wieder geschickt. Das dauert verdammt lange. AUsserdem öffnet es Tür und Tor für SQL-Injections. Parameter sind schneller, weil der Server weis das sich nur die Daten geändert haben, ausserdem werden SQL-Kommandosa in Parametern icht erkannt und 'nur' als Text bewertet (=Schutz vor Injections).
Andreas
Code: Alles auswählen
sl := TStringList.Create;
try
sl.Delimiter := ' ';
sl.QuoteChar := #$0;
sl.DelimitedText := Origin;
SQLQuery1.Close;
SQLQuery1.Params.Clear;
SQLQuery1.SQL.Text := 'INSERT INTO tblDictonary (Wort) VALUES (:sWort)';
SQLQuery1.Prepare;
for i := 0 to sl.Count - 1 do
begin
SQLQuery1.ParamByName('sWort').AsString:= sl[i];
SqlQuery1.ExecSQL;
//SqlTransaction1.Commit;
if i mod 1000 = 0 then
begin
SqlTransaction1.Commit;
Form1.Caption := IntToStr(i);
end;
end;
finally
sl.Free;
end;
und das ist IMHO auch sicherer
Code: Alles auswählen
function LoadFile(FilePath: string): string;
var
fm: tfilestream;
s: string;
begin
fm := tfilestream.Create(FilePath, fmopenread);
try
setlength(s, fm.size);
fm.Read(s[1], fm.size);
finally
fm.Free;
end;
Result := s;
setlength(s, 0);
end;
Edit: Das sl.free hat nur bei der sqlite Variante gefehlt. Das mit den Parametern und dem Prepare kann drastische geschwindigkeits vorteile bringen, da der sog. Ausführungsplan nicht neu erstellt werden muß. Wenn du jedesmal das SQL-Statement angibst, so wird auch in den SQL-DB Komponenten das ganze Statement neu verarbeitet, die Strukturen verworfen und neu erstellt und dann dem Server die Änderungen wieder geschickt. Das dauert verdammt lange. AUsserdem öffnet es Tür und Tor für SQL-Injections. Parameter sind schneller, weil der Server weis das sich nur die Daten geändert haben, ausserdem werden SQL-Kommandosa in Parametern icht erkannt und 'nur' als Text bewertet (=Schutz vor Injections).
Andreas
Zuletzt geändert von af0815 am Sa 29. Okt 2016, 21:29, insgesamt 1-mal geändert.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).