AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Insert geschwindigkeit verbessern
Thema durchsuchen
Ansicht
Themen-Optionen

Insert geschwindigkeit verbessern

Ein Thema von Grumble · begonnen am 10. Feb 2005 · letzter Beitrag vom 11. Feb 2005
Antwort Antwort
Benutzerbild von Grumble
Grumble

Registriert seit: 19. Mär 2003
Ort: Dresden
203 Beiträge
 
Delphi 6 Enterprise
 
#1

Insert geschwindigkeit verbessern

  Alt 10. Feb 2005, 13:27
Datenbank: Firebird • Version: 1.5.1 • Zugriff über: Sql (Zeos)
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:
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;
in der while schleife lege ich den parameter c immer neu fest und schreibe per execsql in die db, nach schleifendurchlauf dann commit...
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?
gruss
Grumble

... moege der code mit dir sein ...
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.016 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#2

Re: Insert geschwindigkeit verbessern

  Alt 10. Feb 2005, 13:42
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
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
PRehders

Registriert seit: 31. Okt 2003
Ort: Hamburg
42 Beiträge
 
#3

Re: Insert geschwindigkeit verbessern

  Alt 10. Feb 2005, 13:47
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
Peter Rehders
Man sollte niemanden ernst nehmen, der sich ernst nimmt.
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#4

Re: Insert geschwindigkeit verbessern

  Alt 10. Feb 2005, 13:56
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:
   // 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;
Auserdem:
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');
   ...
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von Grumble
Grumble

Registriert seit: 19. Mär 2003
Ort: Dresden
203 Beiträge
 
Delphi 6 Enterprise
 
#5

Re: Insert geschwindigkeit verbessern

  Alt 10. Feb 2005, 13:58
also netzwerkbelastung habe ich nicht, da die db lokal ist

ich probier nochmal rum, danke
gruss
Grumble

... moege der code mit dir sein ...
  Mit Zitat antworten Zitat
VizeTE

Registriert seit: 31. Dez 2002
178 Beiträge
 
Delphi 5 Enterprise
 
#6

Re: Insert geschwindigkeit verbessern

  Alt 11. Feb 2005, 10:17
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
ZQ.DisableControls und danach
ZQ.EnableControls aufrufen. Wahrscheinlich hast du ja selbts daran gedacht aber man weiß ja nie ;)
  Mit Zitat antworten Zitat
Robert_G
(Gast)

n/a Beiträge
 
#7

Re: Insert geschwindigkeit verbessern

  Alt 11. Feb 2005, 10:25
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.
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.
  Mit Zitat antworten Zitat
Benutzerbild von Grumble
Grumble

Registriert seit: 19. Mär 2003
Ort: Dresden
203 Beiträge
 
Delphi 6 Enterprise
 
#8

Re: Insert geschwindigkeit verbessern

  Alt 11. Feb 2005, 10:32
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?
gruss
Grumble

... moege der code mit dir sein ...
  Mit Zitat antworten Zitat
Robert_G
(Gast)

n/a Beiträge
 
#9

Re: Insert geschwindigkeit verbessern

  Alt 11. Feb 2005, 10:36
Zitat von Grumble:
meinst du ich soll das primary key feld raushaun?
uff Bloss nicht!
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?
Ich weiß nicht wie gut FB BLOBs hndhabt, aber ich würde darauf wetten, dass ein BLOB schneller ist.
  Mit Zitat antworten Zitat
Benutzerbild von Grumble
Grumble

Registriert seit: 19. Mär 2003
Ort: Dresden
203 Beiträge
 
Delphi 6 Enterprise
 
#10

Re: Insert geschwindigkeit verbessern

  Alt 11. Feb 2005, 11:10
also die groesse von varchar scheint auch nicht die rolle zu spielen...
habs mal mit varchar(400) getestet... lief aufs selbe raus
gruss
Grumble

... moege der code mit dir sein ...
  Mit Zitat antworten Zitat
Antwort Antwort


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 13:08 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