![]() |
Datenbank: Firebird • Version: 1.5.1 • Zugriff über: Sql (Zeos)
Insert geschwindigkeit verbessern
hallo leute,
ich moechte mich mal an die profis hier wenden und frag ob und wie ich das schreiben in die db schneller machen kann, dazu hier erstmal der quellcode:
Delphi-Quellcode:
in der while schleife lege ich den parameter c immer neu fest und schreibe per execsql in die db, nach schleifendurchlauf dann commit...
if DM.ZCONDATA.Connected=false then DM.ZCONDATA.Connect;
// schreiben der asset_data DM.ZQ.SQL.Clear; dm.ZQ.SQL.Add('INSERT INTO ASSET_DATA'); dm.ZQ.SQL.Add('(ASSET_ID'); //a dm.ZQ.SQL.Add(',GEO_ID'); //b dm.ZQ.SQL.Add(',DATA)'); //c dm.ZQ.SQL.Add('values'); dm.ZQ.SQL.Add('(:a,:b,:c);'); dm.ZQ.ParamByName('a').AsInteger:=caid; dm.ZQ.ParamByName('b').AsInteger:=0; } lasset:=Tstringlist.Create; AssignFile(tempfile,OpeniDLG.FileName); Reset(tempFile); While not EOF(tempFile) do begin c:=c+1; ReadLN(tempFile,tempString); if c=1 then begin if (firstline) then begin dm.ZQ.ParamByName('c').AsString:=tempstring; dm.ZQ.ExecSQL; end; end else if c>1 then begin dm.ZQ.ParamByName('c').AsString:=tempstring; dm.ZQ.ExecSQL; end; bkrehab_fprogress.pb_progress.Position:=filepos(tempfile); bkrehab_fprogress.Panel2.Repaint; lasset.Append(tempstring) end; dm.ZQ.SQL.Clear; dm.zq.SQL.add('commit retain;'); dm.ZQ.ExecSQL; nun dauert das ganze bei ca. 6500 datensaetzen doch recht lange... ich hab mal was gelesen dass stored procedures schneller sind ... aber wie macht man sowas, geht das mit zeos... ist es ratsam? ich habe ja keine erfahrung damit... oder gibts andere moeglichkeiten die geschwindigkeit zu verbessern? |
Re: Insert geschwindigkeit verbessern
Es gibt noch andere Möglichkeiten, das zu regeln.
Ich weiß nur nicht, welche am schnellsten ist, aber ich erwähn sie mal: - Query auf CachedUpdates stellen, Sätze einfügen und anschließend mit ApplyUpdates übertragen - In der Schleife ein Script aufbauen und das mit der TZSQLProcessor ausführen |
Re: Insert geschwindigkeit verbessern
Hallo,
wenn die Table mehrere Indizes hat, kommt noch ein weiterer Weg in Frage. Es ist nämlich auch die Frage, in welchem Rahmen dieser Masseninsert stattfindet: Wenn es sich um einmalige Aktionen handelt, oder solche, die nur zu definierten Zeitpunkten ohne andere Aktivitäten stattfinden, solltest Du dir überlegen: - Indizes auf die Table löschen - Inserts durchführen - Indizes wieder einrichten das geht normalerweise sehr viel schneller, weil die DB das anders organisieren kann als einen Masseninsert in schon bestehende Index-Dateien. Bis dann Peter |
Re: Insert geschwindigkeit verbessern
Du könntest viele (~500) INSERT - Anweisungen in einer Stringliste zwischen speichern
und dann in einem Rutsch ausführen. Diese würde den Netzwerkverwerk deutlich reduzieren, da statt vieler kleiner Pakete nur wenige grosse Pakete gesendet würden. Dies geht aber nur, wenn die Datenbank, die Treiber und die Zeos-Komponenten diese mehrfachen Befehle unterstützen (MS SQL Server + ADO kann das). Mach einfach einen Test:
Delphi-Quellcode:
Auserdem:
// Beispiel für 2 Insert auf einmal
// SQL Anweisungen mit ; getrennt DM.ZQ.SQL.Clear; dm.ZQ.SQL.Add('INSERT INTO ASSET_DATA Values(20, 30, 'Test1);'); dm.ZQ.SQL.Add('INSERT INTO ASSET_DATA Values(20, 60, 'Test2);'); dm.ZQ.ExecSQL;
Delphi-Quellcode:
var
qry : TQuery; begin qry := dm.ZQ; // jetzt wird nur noch mit "qry" gearbeitet; dies spart etwas Rechenzeit qry.SQL.Clear; qry.SQL.Add('INSERT INTO ASSET_DATA'); ... |
Re: Insert geschwindigkeit verbessern
also netzwerkbelastung habe ich nicht, da die db lokal ist
ich probier nochmal rum, danke |
Re: Insert geschwindigkeit verbessern
mal noch ein Gedanke in eine ganz andere Richtung...falls der Inhalt deines "ZQ"-Querys mit Hilfe von Komponenten wie "DBGrids" oder ähnlichen angezeigt wird dann vor der Schleife
Delphi-Quellcode:
und danach
ZQ.DisableControls
Delphi-Quellcode:
aufrufen. Wahrscheinlich hast du ja selbts daran gedacht aber man weiß ja nie ;)
ZQ.EnableControls
|
Re: Insert geschwindigkeit verbessern
Firebird kann kein Bulk DML, d.h.: Es wird IMMER auf einzelne Statements hinauslaufen.
Du einzig mögliche Optimierung, die ich erkennen kann wäre shmias Vorschlag mit dem Script. Oder zusätzliche eine SP, die das Statement nochmal verkleinert. :gruebel: Aber das sind nur kleine Friemeleien, viel ändern wird sich da nix. hmm... Hast du in der Tabelle Indizes auf String-felder? Benutzt du die auch? Wenn nicht: schmeiß die weg, das dürfte DML auf die Tabelle massiv beschleunigen. ;) Die Idee mit dem Entfernen und Neuanlegen von Indizes will ich überhört haben. ;) Solche Friemeleien bekommst du niemals ( :!: ) validiert, und eine nicht validierbare DB ist eine sinnlose DB. |
Re: Insert geschwindigkeit verbessern
also die tabelle die das ganze 'bremst' ist folgendermassen aufgebaut:
NAME TYPE ASSETDATA_ID INTEGER PK ASSET_ID INTEGER FK GEO_ID INTEGER DATA VARCHAR(32000) meinst du ich soll das primary key feld raushaun? |
Re: Insert geschwindigkeit verbessern
Zitat:
Ich meinte ungenutzte string-indizes! (welche es bei dir anscheinend nicht gibt) Du solltest dir aber vielleicht überlegen, ob ein fortlaufender Index besser als PK passt. Dabei ist es für den kleinen Firebird auch nicht so schwierig die Eindeutigkeit zu prüfen. Und du musst in Abfragen nur auf ein Feld verweisen, nicht auf 2. ;) Und 32.000 Zeichen in einem Feld? :shock: Ich weiß nicht wie gut FB BLOBs hndhabt, aber ich würde darauf wetten, dass ein BLOB schneller ist. ;) |
Re: Insert geschwindigkeit verbessern
also die groesse von varchar scheint auch nicht die rolle zu spielen...
habs mal mit varchar(400) getestet... lief aufs selbe raus |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:29 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz