Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi viele Generatoren auf einmal "holen" (https://www.delphipraxis.net/86483-viele-generatoren-auf-einmal-holen.html)

hoika 14. Feb 2007 19:59

Datenbank: FB • Version: 1.5 • Zugriff über: egal

viele Generatoren auf einmal "holen"
 
Hallo #,

ich speichere Daten immer wie folgt ab,

1. Hole per SP einen neuen Id (Generator)
2. Mache ein Insert mit diesem neuen ID-Wert

Bei vielen Datensätzen (~2000) brauchst das aber so seine Zeit,
weil 2000mal die SP ausgeführt wird.

Jetzt könnte ich mir ja per (vielleicht anderer) SP
gleich 10 Werte am Stück belegen, per gen_id(gen_XXX, 10).
die 10 nur so als Beispiel.

Der Generator wird um 10 erhöht,
ich erhalte den neuen Wert und benutze aber auch die 9 Werte davor.

Das gen_id ist ja atomar, d.h., intern wird das serialisiert,
falls zwei Clients zufällig quasi gleichzeitig die sp aufrufen.


Habe ich hier einen Denkfehler oder klappt das ???


Danke
Heiko

Hansa 14. Feb 2007 20:32

Re: viele Generatoren auf einmal "holen"
 
mehrere Fragen :

1. was heißt lange ? 2000 Datensätze ist nicht ungewöhnlich viel.
2. was genau wird von der SP eingetragen ? Nur die ID oder noch was anderes ?
3. Wie sollen die "9 Werte davor" denn benutzt werden.

Du weißt ja hoffentlich, dass die Generatoren als einziges in IB/FB NICHT der Transaktionsseuerung unterliegen. Also nichts mehr mit Rollback + Co. Ehrlich gesagt, zumindest ich habe etwas, das auch nur entfernt in die Richtung der Frage geht, noch nie gesehen. :shock: Aber wer weiß.

hanspeter 14. Feb 2007 20:39

Re: viele Generatoren auf einmal "holen"
 
Zitat:

Zitat von hoika
Hallo #,


Habe ich hier einen Denkfehler oder klappt das ???


Danke
Heiko

Das sollte klappen. Ich mache es schon ewig und 3 Tage genauso.

GEN_ID(GEN_Autolink,100); stellt einen Nummernraum zur Verfügung.

Eine einzelne Function in einer SP sollte nicht durch andere Client unterbrechbar sein.

Gruß Peter

mkinzler 14. Feb 2007 20:41

Re: viele Generatoren auf einmal "holen"
 
Ich würde auch versuchen, den Umfang der SP zu minimieren, bzw. den Flaschenhals zu eliminieren. Die Inkrementierung des Generators durch die Semaphorenfunktion dürfte nicht der Grund sein.

hoika 14. Feb 2007 23:11

Re: viele Generatoren auf einmal "holen"
 
Hallo,

hanspeter: guutt, dann werd ich das mal probieren

zu den anderen ;)
Transaktion ist mir egal, es geht um AutoInc-Erzeugung
ob da Lücken enstehen, is Brust

Das Problem ist, dass es halt 2000 Queries (naja Execute Procedure)
übers Netz sind, die ja nicht notwendig sind.

Die SP gibt übrigens exakt ein Integer zurück,
mit dem dann das "Insert into Table_bla" gemacht wird.


Heiko

hoika 15. Feb 2007 07:01

Re: viele Generatoren auf einmal "holen"
 
Hansa,

der Punkt ist, das die betreffende Methode ziemlich lahm ist
(15 sec übers Netz)
Es werden so etwas 20000 Datensätze in einem Rutsch geschrieben (insert)
und ich will die SQL-Zugriffe minimieren.
Das Insert bekomme ich nicht weg ;), aber die 20000 GetNewId-SPs dann schon.

Ich weiss, wieviele Datensätze geschrieben werden,
also erhöhe ich den Generatorwert gleich um 20000 und
benutze die jetzt freien Werte 1-20000 (+alter Generatorwert).


Heiko

merlin17 15. Feb 2007 07:26

Re: viele Generatoren auf einmal "holen"
 
Heiko,

warum holst Du Dir überhaupt den Gen-Wert... erstelle doch einfach einen Trigger (BI) und füge dort
die PK-Spalte mit dem GenID; in Deinem Insert entfällt dann die ID-Spalte als Valuewert und IB/FB erledigt
dass mehr oder weniger performance irrevelant im Background ...

Delphi-Quellcode:
begin
   if (NEW.ID is null) then
         NEW.ID = GEN_ID(G_RUECKFRAGE, 1);
end
:-) thomas

hoika 15. Feb 2007 07:37

Re: viele Generatoren auf einmal "holen"
 
Hallo,

weil ich die neue Id (PK) meist gleich benutzen muss (Master-Detail).
Und sage jetzt bitte nicht "select Max(id)"
liefert dir doch die neue Id ;)


Heiko

mkinzler 15. Feb 2007 07:39

Re: viele Generatoren auf einmal "holen"
 
Welche Zugriffsbibliothek verwendest du?

alex517 15. Feb 2007 09:26

Re: viele Generatoren auf einmal "holen"
 
Hallo Heiko,


Zitat:

Zitat von hoika
der Punkt ist, das die betreffende Methode ziemlich lahm ist
(15 sec übers Netz)

In meiner Umgebung brauche ich tatsächlich 26 sek für 20.000 IDs! :?

Zitat:

Zitat von hoika
Ich weiss, wieviele Datensätze geschrieben werden,
also erhöhe ich den Generatorwert gleich um 20000 und
benutze die jetzt freien Werte 1-20000 (+alter Generatorwert).

Zuerst dachte ich es wäre besser über eine SP die ID einzeln hochzuzählen,
in der Art
SQL-Code:
 while (i <= ANZAHL) DO
 begin
   id = GEN_ID(GEN_TEST, 1);
   suspend;
 end
aber nach einigem Nachdenken, bin ich aber zu dem Schluss gekommen, dass es auch
mit EINER Erhöhung um die gesamte Anzahl gehen muss.
Man kann dann die IDs beginnend mit Generatorwert-Anzahl bis Generatorwert verwenden.

alex

hoika 15. Feb 2007 10:46

Re: viele Generatoren auf einmal "holen"
 
Hallo,

Zugriff: Bde (jaja) :=)

alex: genau
gen_id(gen_xxx,20000)

Das war so meine Überlegung.
Ich habe hier allerdings auch noch festgestellt,
dass die TStoredProc nicht prepared wird,
das liegt einfach daran, dass ich eine generische Methode habe,
die basierend auf dem Tabellennamen die richtige SP aufruft.

Das könnte man natürlich ändern,
aber wenn es mit dem Generator viel leichter ist,
lasse ich die generische Methode für "normale" Inserts
und wenn es klemmt, wird das an dieser Stelle geändert.

mkinzler:
solche Sachen wie "Generatorwert" (IBX ?) will ich nicht benutzen,
weil der Plan immer noch ist, mal eine andere DB zu unterstützen.



Heiko

shmia 15. Feb 2007 11:06

Re: viele Generatoren auf einmal "holen"
 
Also ich sehe da keinen Denkfehler, sondern das dürfte das effektivste Verfahren sein.
Wenn sich ein Client also gleich 10 oder 100 Nummern reserviert, dann kann er
ohne weitere Rückfrage entsprechend viele Inserts absetzen.
Sollte der Fall eintreten, dass Client- oder Serverseitig ein Fehler auftritt, sind die Nummern eben verloren, aber das sollte nicht stören.
Auch bei einem Rollback wären alle Inserts weg und damit die gezogenen Nummern verloren.
Es ist aber beim PK nicht zwingend eine lückenlose Folge nötig.

Da auf dem Server kein Trigger benötigt wird, entfällt hier auch diese Serverseitige Belastung.
Noch effizienter wird die Sache, wenn blockweise Insert-Anweisung gesammelt abgesetzt werden.
Damit entfällt der x-fache Netzwerkverkehr.

Wenn du also 100 Nummern reserviert, dann 100 Inserts für die Mastertabelle + die Inserts für die Detailtabelle generierst (in StringListe sammeln) erreichst du die maximal mögliche Einfügegeschwindigkeit.

hoika 15. Feb 2007 12:38

Re: viele Generatoren auf einmal "holen"
 
Hallo,

"" Wenn du also 100 Nummern reserviert, dann 100 Inserts für die Mastertabelle + die Inserts für die Detailtabelle generierst (in StringListe sammeln) erreichst du die maximal mögliche Einfügegeschwindigkeit. ""

Meinst du das mit blockweise ?


Heiko

shmia 15. Feb 2007 13:58

Re: viele Generatoren auf einmal "holen"
 
Zitat:

Zitat von hoika
"" Wenn du also 100 Nummern reserviert, dann 100 Inserts für die Mastertabelle + die Inserts für die Detailtabelle generierst (in StringListe sammeln) erreichst du die maximal mögliche Einfügegeschwindigkeit. ""
Meinst du das mit blockweise ?

Ja, anstatt jeden Insert einzeln auf die Reise zu schicken, werden die Inserts gesammelt und dann im Block abgeschickt.
Das bedeutet aber, dass man nicht den bequemen Weg über Datasets nehmen kann (Query.Edit; query['Feld'] := ...; query.Post;) sondern man muss die Inserts als Strings zusammenbauen.
Über Connection.Execute() kann man die gesammelten Inserts absetzen.
Die Anweisungen werden durch einen Strichpunkt getrennt. (DBMS abhängig)
Nicht jedes DBMS erlaubt mehrfache SQL-Anweisungen (MS-SQL-Server: ja, MS-Access: nein, IB: ???).

Nur mit dieser Technik konnte ich z.B. 1.3 Mio Datensätze innerhalb von ~ 40 Min in eine MS SQL-Server Datenbank einfügen.

mkinzler 15. Feb 2007 14:00

Re: viele Generatoren auf einmal "holen"
 
Zitat:

Nicht jedes DBMS erlaubt mehrfache SQL-Anweisungen (MS-SQL-Server: ja, MS-Access: nein, IB: ???).
IB/FB: Ja ; über BDE ?

hoika 15. Feb 2007 14:02

Re: viele Generatoren auf einmal "holen"
 
Hallo,

das mit ms-sql hatte ich (im dotnet-magazin) auch schon mal gelesen.
FB kann das ???
Mit welcher Komponente denn ?

Ich schwanke noch zwischen FIBPlus und UIB.


Heiko

mkinzler 15. Feb 2007 14:22

Re: viele Generatoren auf einmal "holen"
 
Mehrere Inserts am Stück geht nicht mit einet Query-Komponent sondern mit einer Script-Kompo (TIBSript, TZSQLProcessor, TIBCScript, TUIBScript). Die Syntax könnte natürlich von der des MSSQL abweichen.

hoika 15. Feb 2007 16:00

Re: viele Generatoren auf einmal "holen"
 
Hm,

interessant ist das schon,
mal sehen.


Heiko


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:17 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-2025 by Thomas Breitkreuz