Speicherverbrauch bei Insert-Statements

27/11/2011 - 00:39 von A. Kuckelberg | Report spam
Hallo NG,
ich füge in eine Firebird-DB per TIBQuery-Objekt viele Datensàtze über
prepared-Statements ein. Grob sieht der Code so aus:

// Datenbankverbindung einrichten
IBConn := TIBDatabase.Create(nil);
IBConn.DatabaseName := <Datenbankstring>;
IBConn.Params.Add('user_name=' + <User_Name>);
IBConn.Params.Add('password=' + <Password>);
IBConn.LoginPrompt := false;
IBConn.Open;

// Query anlegen
IBQuery := TIBQuery.Create (nil);
IBQuery.Database := IBConn;
IBQuery.CachedUpdates := False;
IBQuery.DisableControls;
IBQuery.SQL.Clear;
IBQuery.SQL.Add ('INSERT INTO tabelle (ID, WERT) VALUES (:id, :wert)');

// Und jetzt viele Werte schreiben
for i := 0 to 100000 do begin
IBQUERY.ParamByName ('ID').AsInteger := i;
IBQUERY.ParamByName ('WERt').AsInteger := i;
IBQUERY.EXECSQL;
end;
IBQUERY.FREE;

Das Problem ist nun, dass nach der Schleife der Speicherverbrauch des
ausführenden Programms stark gestiegen ist (laut Taskmanager). Die
Speichernutzung geht auch nach dem Free nicht zurück. Verwendet wird der
Firebird-Embedded-Server 2.1.4 bzw. 2.5.

Nach meinem bisherigen Verstàndnis sollte doch die Speichernutzung
innerhalb der Schleife einigermaßen konstant bleiben oder zumindest nach
der Schleife wieder freigegeben werden, oder?

Handelt es sich hier um ein Speicherleck? Ist der Ansatz und die
Erwartung mit "konstanter" Speicherauslastung innerhalb der Schleife
falsch oder ist die Datenbankverbindung oder die Query falsch konfiguriert?

Das gleiche Verhalten zeigt sich auch, wenn statt TIBQuery TIBSQL
verwendet wird.

Hinweise oder weitere Hilfe wàre hier sehr willkommen.
Danke!

Alexander
 

Lesen sie die antworten

#1 A. Kuckelberg
28/11/2011 - 23:41 | Warnen spam
Hallo zusammen,
inzwischen habe ich rausgefunden, dass ein IBConn.Close gefolgt von
einem IBConn.Open die Speichernutzung wieder runterdrückt (aber ein
Commit einer im Beispiel vergessenen Transaktion hat keine Auswirkung).
Scheinbar werden die Insert-Werte gepuffert, das wirkliche Schreiben auf
Festplatte erfolgt wohl erst mit dem Clode/Open.
Gibt es explizite Flush-Anweisungen, um diesen open/close-Umweg zu
vermeiden? Oder Parameter/Konfigurationseinstellungen, die das Ganze
direkt Speicherschonender handhaben?
Alexander

Hallo NG,
ich füge in eine Firebird-DB per TIBQuery-Objekt viele Datensàtze über
prepared-Statements ein. Grob sieht der Code so aus:

// Datenbankverbindung einrichten
IBConn := TIBDatabase.Create(nil);
IBConn.DatabaseName := <Datenbankstring>;
IBConn.Params.Add('user_name=' + <User_Name>);
IBConn.Params.Add('password=' + <Password>);
IBConn.LoginPrompt := false;
IBConn.Open;

// Query anlegen
IBQuery := TIBQuery.Create (nil);
IBQuery.Database := IBConn;
IBQuery.CachedUpdates := False;
IBQuery.DisableControls;
IBQuery.SQL.Clear;
IBQuery.SQL.Add ('INSERT INTO tabelle (ID, WERT) VALUES (:id, :wert)');

// Und jetzt viele Werte schreiben
for i := 0 to 100000 do begin
IBQUERY.ParamByName ('ID').AsInteger := i;
IBQUERY.ParamByName ('WERt').AsInteger := i;
IBQUERY.EXECSQL;
end;
IBQUERY.FREE;

Das Problem ist nun, dass nach der Schleife der Speicherverbrauch des
ausführenden Programms stark gestiegen ist (laut Taskmanager). Die
Speichernutzung geht auch nach dem Free nicht zurück. Verwendet wird der
Firebird-Embedded-Server 2.1.4 bzw. 2.5.

Nach meinem bisherigen Verstàndnis sollte doch die Speichernutzung
innerhalb der Schleife einigermaßen konstant bleiben oder zumindest nach
der Schleife wieder freigegeben werden, oder?

Handelt es sich hier um ein Speicherleck? Ist der Ansatz und die
Erwartung mit "konstanter" Speicherauslastung innerhalb der Schleife
falsch oder ist die Datenbankverbindung oder die Query falsch konfiguriert?

Das gleiche Verhalten zeigt sich auch, wenn statt TIBQuery TIBSQL
verwendet wird.

Hinweise oder weitere Hilfe wàre hier sehr willkommen.
Danke!

Alexander

Ähnliche fragen