AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Insert Optimierung

Ein Thema von Franzelchen · begonnen am 2. Mär 2012 · letzter Beitrag vom 4. Mär 2012
Antwort Antwort
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.316 Beiträge
 
Delphi 12 Athens
 
#1

AW: Insert Optimierung

  Alt 2. Mär 2012, 22:57
Jupp, eine Schleife mit dem zusammengefassten Statement und größeren Schritten
Der Vorteil an dem indizierten Indize und nicht den Namentlichen wäre, daß man eine innere Schleife befüllen könnte und so z.B. 100 Werte zusammenfassen könnte.
(müßte man mal ausprobieren, welche Größe halbwegs optimal ist)

und zum Schluß nicht vergessen, daß da noch ein paar Zeilen übrigbleiben können.


Entweder man bastelt das Insert-Statement als String zusammen, für die Restlichen und vorher einmal für alle Teile
oder man läßt den Rest über ein einfaches Insert, mit je einem der Restwerte, übertragen.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#2

AW: Insert Optimierung

  Alt 3. Mär 2012, 08:46
Viel schneller geht es, wenn Du die Daten in eine Textdatei packst und dann per bulk insert in deine DB kopierst. So sollte das in wenigen Sekunden erledigt sein.

Wenn Du unbedingt mit INSERT-Befehlen arbeiten musst, dann könnte es viel schneller sein, wenn Du dir das Skript zunächst in einer Stringliste zusammenbaust und dann als ein Befehl innerhalb einer Transaktion ausführen lässt.

Wo ist der Fehler?
i wird nicht initialisiert

Geändert von Furtbichler ( 3. Mär 2012 um 08:49 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.316 Beiträge
 
Delphi 12 Athens
 
#3

AW: Insert Optimierung

  Alt 3. Mär 2012, 11:46
Beim Bulk-Insert mußt du aber aufpassen.

Klient und Datenbankserver müssen auf die selben Speicherplätze zugreifen und sollten womöglich auch noch über die selben Netzwerkadressen verfügen (abgesehn man nutzt im Klient einen Dateipfad, und gibt dann dem Server einen anderen Pfad mit, unter welchem er die Datei findet)

Bei Postgres-COPY könnte man zwar auch über STDIN die Daten übergeben, aber ich hatte nicht rausbekommen, ob und wie man das via einem ExecSql-Befehl durch ein Delphi-Programm mit übertragen kann.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.213 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Insert Optimierung

  Alt 3. Mär 2012, 11:49
Wo ist der Fehler?
i wird nicht initialisiert
Von Vorteil ist wer lesen kann. Nicht umsonst gibt der Compiler Warnmeldungen aus.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Franzelchen

Registriert seit: 22. Mär 2007
82 Beiträge
 
#5

AW: Insert Optimierung

  Alt 3. Mär 2012, 14:14
Delphi-Quellcode:
var i:Integer;
var startzeit,stopzeit : TDateTime;

begin
startzeit := now;
i := 0; // Initialisierung von i
Screen.Cursor := crHourGlass;
ZConnection.Database := 'c:\msql\firedb.fdb';
 Zquery1.SQL.Text:='INSERT INTO TestTabelle (Wert1, Wert2) VALUES(:v1, :v2), (:v3, :v4), (:v5, :v6), (:v7, :v8), (:v9, :v10)';
 while i <= SG1.RowCount-1 do
  begin
       with ZQuery1.params do
       begin
        ParamValues['v1']:=SG1.Cells[0, i];
        ParamValues['v2']:=SG1.Cells[1, i];
        ParamValues['v3'] := SG1.Cells[0, i + 1];
        ParamValues['v4'] := SG1.Cells[1, i + 1];
        ParamValues['v5'] := SG1.Cells[0, i + 2];
        ParamValues['v6'] := SG1.Cells[1, i + 2];
        ParamValues['v7'] := SG1.Cells[0, i + 3];
        ParamValues['v8'] := SG1.Cells[1, i + 3];
        ParamValues['v9'] := SG1.Cells[0, i + 4];
        ParamValues['v10']:= SG1.Cells[1, i + 4];

      end; // with
  ZQuery1.ExecSQL;
   i := i+5;
  end; // i
Screen.Cursor := crDefault;
stopzeit := now;
Panel1.Caption :='SuchZeit : '+ FormatDateTime('nn:ss:zzz', StopZeit - StartZeit) ;
end;
Das Problem dabei: Wo vorher keine Fehlermeldung war, erscheint jetzt

Code:
Benachrichtigung über Debugger-Exception
---------------------------
Im Projekt Project2.exe ist eine Exception der Klasse EZSQLException aufgetreten. Meldung: 'SQL Error: Dynamic SQL Error SQL error code = -104 Token unknown - line 1, column 51 ,. Error Code: -104. Invalid token The SQL: INSERT INTO Testtabelle (Wert1, Wert2) VALUES(?, ?), (?, ?), (?, ?), (?, ?), (?, ?); '. Prozeß wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
---------------------------
OK  Hilfe  
---------------------------
Spalte 51?? Es gibt nur 2 Spalten.

Bitte um Übersetzung dieser Fehlermeldung.


@ Furtbichler @ Himitsu

bulk insert Erkläre mir einer diesen Begriff. Ich meine gelesen zu haben, daß bulk insert bei Firebird nicht möglich ist.
Der Link von Furtbichler verweist auf externalTables. Um dies nutzen zu können, muß ich doch mir unbekannte Veränderungen an der firebird.conf Datei vornehmen!??

Beim Bulk-Insert mußt du aber aufpassen.

Klient und Datenbankserver müssen auf die selben Speicherplätze zugreifen und sollten womöglich auch noch über die selben Netzwerkadressen verfügen (abgesehn man nutzt im Klient einen Dateipfad, und gibt dann dem Server einen anderen Pfad mit, unter welchem er die Datei findet)
Klient und Server sind auf ein und demselben Rechner. Reicht das?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.316 Beiträge
 
Delphi 12 Athens
 
#6

AW: Insert Optimierung

  Alt 3. Mär 2012, 14:22
Joar, wenn dann noch die Zugriffsrechte auf das Verzeichnis passend sind.
Bei uns auf'm Server hab ich ein privates virtuelles SUBST-Laufwerk, wo meine Verzeichnisse reingemappt sind ... der SQL-Server hat auf diese nicht direkt Zugriff drauf, auf dieses Arbeits-Laufwerk, außer über den originalen Pfad.


Nicht Spalte 51, sondern Zeichen 51.
Das ist auf den SQL-Text bezogen > Zeile und Spalte/Zeichen/Buchstabe.
Die schließende Klammer ) nach dem ersten Wertepaar?

[edit]
Oder das Komma danach?
http://www.firebirdsql.org/refdocs/l...21-insert.html
Eventuell kann Firebird das nicht?

Vielleicht dann einfach so. (Das andere wäre halt kürzer)
SQL-Code:
INSERT INTO Testtabelle (Wert1, Wert2) VALUES (?, ?);
INSERT INTO Testtabelle (Wert1, Wert2) VALUES (?, ?);
INSERT INTO Testtabelle (Wert1, Wert2) VALUES (?, ?);
INSERT INTO Testtabelle (Wert1, Wert2) VALUES (?, ?);
INSERT INTO Testtabelle (Wert1, Wert2) VALUES (?, ?);
Es geht ja einfach nur darum, den Traffik und die Anzahl der Anfragen an den Server zu verringern.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu ( 3. Mär 2012 um 14:29 Uhr)
  Mit Zitat antworten Zitat
Franzelchen

Registriert seit: 22. Mär 2007
82 Beiträge
 
#7

AW: Insert Optimierung

  Alt 3. Mär 2012, 15:02
So etwa??

Delphi-Quellcode:
procedure TForm1.InputDataset3Click(Sender: TObject);
var i:Integer;
var startzeit,stopzeit : TDateTime;

begin
i := 0;
startzeit := now;
Screen.Cursor := crHourGlass;
ZConnection.Database := 'c:\msql\firedb.fdb';
 Zquery1.SQL.Text:='INSERT INTO Testtabelle (Wert1, Wert2) VALUES(:v1, :v2)';
 Zquery1.SQL.Text:='INSERT INTO Testtabelle (Wert1, Wert2) VALUES(:v3, :v4)';
 Zquery1.SQL.Text:='INSERT INTO Testtabelle (Wert1, Wert2) VALUES(:v5, :v6)';
 Zquery1.SQL.Text:='INSERT INTO Testtabelle (Wert1, Wert2) VALUES(:v7, :v8)';
 Zquery1.SQL.Text:='INSERT INTO Testtabelle (Wert1, Wert2) VALUES(:v9, :v10)';

 while i <= SG1.RowCount-1 do
  begin
       with ZQuery1.params do
       begin
        ParamValues['v1']:=SG1.Cells[0, i];
        ParamValues['v2']:=SG1.Cells[1, i];
        ParamValues['v3'] := SG1.Cells[0, i + 1];
        ParamValues['v4'] := SG1.Cells[1, i + 1];
        ParamValues['v5'] := SG1.Cells[0, i + 2];
        ParamValues['v6'] := SG1.Cells[1, i + 2];
        ParamValues['v7'] := SG1.Cells[0, i + 3];
        ParamValues['v8'] := SG1.Cells[1, i + 3];
        ParamValues['v9'] := SG1.Cells[0, i + 4];
        ParamValues['v10']:= SG1.Cells[1, i + 4];

      end; // with
  ZQuery1.ExecSQL;
   i := i+5;
  end; // i
Screen.Cursor := crDefault;
stopzeit := now;
Panel1.Caption :='SuchZeit : '+ FormatDateTime('nn:ss:zzz', StopZeit - StartZeit) ;
end;
Kompilierung einwandfrei

Bei Ausführung: Kann Parameter v1 nicht finden

oder müssen die jeweiligen Parameter hinter dem jeweiligen insert Befehl stehen,
aber nein, denn dann stehen die insert Befehle ja innerhalb der while Schleife, in welcher sie ja nichts zu suchen haben (siehe Beitrag 8)

Geändert von Franzelchen ( 3. Mär 2012 um 15:07 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.316 Beiträge
 
Delphi 12 Athens
 
#8

AW: Insert Optimierung

  Alt 3. Mär 2012, 15:08
Du überschreibst ja auch immer wieder die Werte komplett, es gilt also immer nur die letzte Zuweiseung.

Fällt aber bestimmt auf, wen man mal nachsieht/debuggt, was für eine Query letzendlich ausgeführt wird.
Delphi-Quellcode:
ZQuery1.SQL.Text :=
    'INSERT INTO dat12006 (Begriff, Frage) VALUES(:v1, :v2);'#10
  + 'INSERT INTO dat12006 (Begriff, Frage) VALUES(:v3, :v4);'#10
  + 'INSERT INTO dat12006 (Begriff, Frage) VALUES(:v7, :v6);'#10
  + 'INSERT INTO dat12006 (Begriff, Frage) VALUES(:v7, :v8);'#10
  + 'INSERT INTO dat12006 (Begriff, Frage) VALUES(:v9, :v10);';

ZQuery1.SQL.Clear;
ZQuery1.SQL.Add('INSERT INTO dat12006 (Begriff, Frage) VALUES(:v1, :v2);';
ZQuery1.SQL.Add('INSERT INTO dat12006 (Begriff, Frage) VALUES(:v3, :v4);';
ZQuery1.SQL.Add('INSERT INTO dat12006 (Begriff, Frage) VALUES(:v7, :v6);';
ZQuery1.SQL.Add('INSERT INTO dat12006 (Begriff, Frage) VALUES(:v7, :v8);';
ZQuery1.SQL.Add('INSERT INTO dat12006 (Begriff, Frage) VALUES(:v9, :v10);';

with ZQuery1.SQL do begin
  Clear;
  Add('INSERT INTO dat12006 (Begriff, Frage) VALUES(:v1, :v2);';
  Add('INSERT INTO dat12006 (Begriff, Frage) VALUES(:v3, :v4);';
  Add('INSERT INTO dat12006 (Begriff, Frage) VALUES(:v7, :v6);';
  Add('INSERT INTO dat12006 (Begriff, Frage) VALUES(:v7, :v8);';
  Add('INSERT INTO dat12006 (Begriff, Frage) VALUES(:v9, :v10);';
end;
(die letzen beiden Queries lassen sich auch sehrt schön automatisch generieren)
Ein Therapeut entspricht 1024 Gigapeut.
  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 04:33 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