Performanceproblem mit Datenimport

23. September 2009 16:37

Hallo, ich habe einen Dataport erstellt, der mir Artikel importiert in die Tabelle Item. Es ca. 240.000 DS.
Nachdem ich den Import starte, dauert es aber bereits sehr lange ehe man bei 1% ist. Ca. nach 30 min wird dies erst erreicht.
Das wären ja gut 2000 DS in 30 min. Dann frag ich mich wie lange ich warten soll, bis alle 240.000 DS drin sind.
Folgend ist mein Quellcode zum Import:
Code:
VALIDATE("VAT Prod. Posting Group", 'VAT19');
VALIDATE("Inventory Posting Group", 'WEITERVERK');
VALIDATE("Gen. Prod. Posting Group", 'HANDEL');

IF NOT ItemUnitofMeasure.GET(Item."No.",'STÜCK')
THEN BEGIN
     ItemUnitofMeasure.INIT;
     ItemUnitofMeasure."Item No.":= Item."No.";
     ItemUnitofMeasure.Code:= 'STÜCK';
     ItemUnitofMeasure."Qty. per Unit of Measure":=1;
     ItemUnitofMeasure.INSERT;
    END;

VALIDATE("Base Unit of Measure", 'STÜCK');
VALIDATE("Unit Cost",ConvertTextToDec(UnitCost));
VALIDATE("Unit Price", ConvertTextToDec(UnitPrice));

IF NOT ItemDiscGroup.GET(Item."Item Disc. Group")
 THEN BEGIN
        ItemDiscGroup.INIT;
        ItemDiscGroup.VALIDATE(Code,Item."Item Disc. Group");
        ItemDiscGroup.INSERT;
        VALIDATE("Item Disc. Group", ItemDiscGroup.Code);
      END
      ELSE VALIDATE("Item Disc. Group", ItemDiscGroup.Code);
INSERT;


Folgende Eigenschaften sind gesetzt für Item:
DataItemTableView: Sorting (No.)
Autosave = yes
Autoupdate = yes

Die Tabelle Item ist zum Importzeitpunkt komplett leer.
Woran liegt es, dass der Import so langsam läuft. Sollte schon etwas zügiger durchlaufen.

MfG Ralph

Re: Performanceproblem mit Datenimport

23. September 2009 17:04

Welche Arbeitsumgebung Nativ-/ SQL-Server, oder Lokal am PC?

Nur so "laut" gedacht (richtig ne Idee habe ich nicht):
Irgendwelche Properties gesetzt / Filter? -->DataItemTableView (Ok, habe ich gerade gesehen, nur "No.")

Wenn Server: Ist ausreichend DBMS-Cache gesetzt? Datenbankauslastung < 80 % besser < 50 %?

Ich sehe viele VALIDATE, könnten diese verantwortlich sein?

Da z.B. die Buchungsgruppen immer die gleichen sind, diese evtl. nur "einfach" zuweisen mit z.B.:
Code:
"VAT Prod. Posting Group" :=  'VAT19'

(Nur zu anfang der Verarbeitung sicherstellen (OnPreDataport oder so), das es diese gibt.)

Da fällt mir noch ein, in Intervallen ein COMMIT (z.B. alle 1000 DS) absetzten soll Performace-Optimierend sein.
Den Indikator duch einen eigenen "Abschalten" und diesen nur nur im Intervall aktualisieren (macht bei 200.000 sowieso keinen Sinn bei jedem DS!).

Re: Performanceproblem mit Datenimport

23. September 2009 19:24

Also die Datenbank läuft auf einem zentralen SQL-server. Die Datenbankauslastung liegt bei 45%.
Wie groß sollte denn der DBMS-Cache sein? Bisher habe ich da immer mit dem Standard gearbeitet.
Habe auch probiert die VALIDATE-Trigger durch einfache Zuweisungen zu ergänzen. Bringt auch nichts.
Ein Commit denk ich wird auch nicht so viel bewirken. Kann es vllt irgentwie an der Item- Tabelle liegen?

Re: Performanceproblem mit Datenimport

23. September 2009 20:00

Du hast AutoSave = Yes und trotzdem führt dein späteres INSERT zu keinem Laufzeitfehler? Erstaunlich.

Also ich hätte folgendes gemacht:
Alle AutoXY-Werte auf No.

OnBeforeImport-Trigger:
Code:
CLEAR(Item);


OnAfterImport-Trigger:
Code:
INSERT(TRUE);

VALIDATE("VAT Prod. Posting Group", 'VAT19');
VALIDATE("Inventory Posting Group", 'WEITERVERK');
VALIDATE("Gen. Prod. Posting Group", 'HANDEL');

ItemUnitofMeasure.INIT;
ItemUnitofMeasure."Item No.":= "No.";
ItemUnitofMeasure.Code:= 'STÜCK';
ItemUnitofMeasure."Qty. per Unit of Measure" := 1;
IF ItemUnitofMeasure.INSERT THEN; // Wenn auch die Tabelle Item Unit of Measure zum Importzeitpunkt leer ist, dann ohne IF .. THEN

VALIDATE("Base Unit of Measure", 'STÜCK');
VALIDATE("Unit Cost");
VALIDATE("Unit Price");

IF "Item Disc. Group" <> '' THEN BEGIN // nichts unnötigerweise einfügen
  ItemDiscGroup.INIT;
  ItemDiscGroup.Code := "Item Disc. Group";
  IF ItemDiscGroup.INSERT THEN; // auch hier: wenn Tabelle leer, ohne IF ... THEN
END;

VALIDATE("Item Disc. Group");
MODIFY(TRUE);

Aber das alles unter der Prämisse, dass deine "Austauscharbeiten" überhaupt so richtig sind - bin bei sowas immer sehr vorsichtig :-)

Ansonsten wie Mikka schon sagte: Wenn du eine Statusanzeige hast, dann diese entweder komplett deaktivieren oder wenigtens in zeitlichen Abständen oder z.B 500er-Paketen aktualisieren - die schlucken nämlich eine Menge Performance.

Re: Performanceproblem mit Datenimport

23. September 2009 21:01

Hallo RS1709,

ob das Ausschalten des Indikators bei der Anzahl Datensätze in 30 Minuten den Performance-Shub bringt, wage ich zu bezweifeln (2000 Updates à 10ms :wink: ).

Hast du in deiner Datenbank schon Clustered Indexe vergeben (einige 5er NAVs machen das automatisch)? Falls du bei den Schlüsseln keine mit CLustered = an findest, mache das bitte für alle Tabellen, die dein Dataport anfasst (auch für die indirekten bei den Validates). Alternativ schreibe einen Report auf der Tabelle Key, der bei allen Schlüsseln mit Index 1 Clustered = True setzt. Im zweiten Schritt solltest du bei allen Tabellen, die an dem Dataport beteiligt sind, die für den Dataport nicht benötigten Schlüssel deaktivieren (geht auch über die Tabelle Key/Feld Enabled).
Des weiteren solltest du prüfen, wie groß dein Transaktion-Log ist, das wird bei so einem Import nicht gerade kleiner (so 3-4 GB frei dürfens bei der Datenmenge schon sein und wenn automatisch vergrößern, dann richtig (500MB- 1GB) und nicht in 10MB oder 10% Schritten. Das gilt auch für die Datenbankdatei). Solltest du mal mit der 10% Vergrößerungs- Arie angefangen haben, mach eine Datensicherung der Datenbank, und lege sie mit vernünftiger Größe neu an, und spiele die Datensicherung zurück. Achte darauf, das deine NTFS-Volumes des SQL-Servers nie voller als 80% werden, sonst wirds langsam.

Gruß, Fiddi

NACHTRAG:
Was du wahrscheinlich am schnellsten prüfen kannst: Lass den Dataport mal direkt auf dem SQL- Server oder auf einem mit GBit- Ethernet angeschlossenen Rechner laufen. :!: :!:
Zuletzt geändert von fiddi am 24. September 2009 08:09, insgesamt 1-mal geändert.

Re: Performanceproblem mit Datenimport

23. September 2009 21:10

Wenn du es schon ohne VALIDATES probiert hast, ist da im Code nicht mehr viel zu optimieren.
Um das manuelle Dialogfenster zu aktualisieren,einen Zähler mitlaufen laufen und die MODULO Funktion nutzen
Code:
IF pos MOD 500 = 0 then
 Window.UPDATE;

Ganz ohne geht zwar auch, aber dann kann man mittendrin schlecht abbrechen.

Ab 5SP1 kann die Bulk Insert Funktion des SQL-Servers genutzt werden, die sollte das deutlich zügiger schaffen.
Beim SQL-Server ist sonst die Verwendung von IF INSERT ... im Gegensatz zum native nicht performancesteigernd, eher das Gegenteil.

Die Validates sollten ohnehin nur da erfolgen wo sie unbedingt nötig sind, also alle Feldtrigger kontrollieren ob da Code steht, der für die Anlage relevant ist. Ansonsten reicht die Zuweisung.
Code:
Validate ("Unit Cost")
macht z.B. eine überflüssige Prüfung auf vorhandene Posten, die neue Artikel nicht haben. Ansonsten wird da nur bei Lagerabgangsmethode Standard der "Einstandspreis (fest)" mitversorgt. Da die aber nicht gesetzt wurde, ist die Vorgabe FIFO aktiv und damit das Validate unnötig (falls im Trigger keine Individualprogrammierung vorliegt).

Code:
ItemUnitofMeasure."Qty. per Unit of Measure" := 1;

ist überflüssig, da die InitValue für das Feld im Standard schon 1 ist (auch das kontrollieren).

Re: Performanceproblem mit Datenimport

23. September 2009 21:32

fiddi hat geschrieben:...
ob das Ausschalten des Indikators bei der Anzahl Datensätze in 30 Minuten den Performance-Shub bringt, wage ich zu bezweifeln (2000 Updates à 10ms :wink: ).


Hallo Fidi,
ohne das ich eine Grundsatzdiskussion starten will, ich würde gern auf ein Bier wetten :-)
Ohne Anpassungen, wird der Dialog immer aktualisiert, d.h. 200.000 mal
Mit Anpassung nur noch z.B. 2000 mal.

Bei angenommenen 10 ms ergibt sich eine Differenz von: 1.980.000 ms = 1980 Sekunden = 33 Minuten :wink:
(Das ist ein kleines Stück Programmcode, das sich fast immer lohnt)
:greenarrow: In eigenen Tests habe ich mit und ohne Idikator eine Verarbeitungsunterschied von ca. 10 - 25 %. Je nach Art der Verarbeitung.

Aaaaaber, und da stimme ich dir zu es wird nicht die Wurzel allen "Übels" sein.


Nachtrag: Ich habe die Wette durchgestrichen, da ich Deinen Satz erst anders verstanden habe. Ich lade dich lieber mal so auf ein Bier ein :-)
(Mein Rechenbeispiel lass ich aber stehen und zu verdeutlichen, das ein schlecht programmierter Indikator / Dialog die Handbremse "leicht" anzieht.)

Re: Performanceproblem mit Datenimport

23. September 2009 21:57

@mikka,

Ralph schrieb von 2000 Datensätzen, die innerhalb von 30 Minuten Importiert werden. D.h. für mich, dass innerhalb von 30 Min. 2000 Updates à 10ms gemacht werden, was nach Adam Riese 20 Sekunden sind, bezogen auf 30 Minuten macht das ca. 1,1 % der Zeit aus. :mrgreen:

Da gibt es glaube ich lohnenderes, als diesen Indikator :wink: .

Aaaaber auch hier:
Wenn du sehr kurze Ausführungszeiten zwischen den Indikator- Aktualisierungen hast (z.B. bei UdateToolkit), macht es durchaus Sinn, diesen nur in sinnvollen Zeitabständen (Modulos) zu aktualisieren.

Gruß, Fiddi

Re: Performanceproblem mit Datenimport

24. September 2009 22:04

Also, ich habe noch ein paar Versuche gestartet. Aufgefallen ist mir die Systemauslastung von 100% während des Imports. Der Finsql Prozess liegt dabei immer bei 99%.
Habe jetzt mal was ausprobiert. Habe noch eine 2. Datei wo nur die Artikelnummern und Lagerdaten enthalten sind. Habe diese importiert mit den ganzen VALIDATE Triggern soweit es ging und dabei ging der Import wesentlich schneller. Da erschein bereits nach wenigen Sekunden 1%. Meine Vermutung liegt in der Datensatzlänge der TXT Dateien. In der 1. Datei beträgt die die Länge 380 Zeichen und in der 2. Datei ist ein DS gerade mal 96 Zeichen lang. Kann es an dieser Länge liegen, das der Lesevorgang so lange dauert für die 380 Zeichen? Anders kann ich mir das nich erklären. Weil in der 2. Datei läuft alles schnell.

Gruß Ralph

Re: Performanceproblem mit Datenimport

25. September 2009 09:06

Ich kann mir nicht vorstellen, das es an 380 Zeichen liegt!

Könnte es sein, das die zusätzlichen Felder welche enthalten, die viel Schreibzugriffe erfordern (da die Zieltabellen viele Key´s und/oder Buckets haben, oder auch sehr viele Datensätze)?
Oder möglicherweise sind weniger aufendige Validierungen notwendigt (durch die veringerte Anzahl Felder)?

Versuche mit dem Client-Monitor doch mal den Datenimport zu analysieren (jedoch nur mit einer kleineren Testdatei, sonst kommst zu einen Absturz), am besten mit dem "erweiterten" aus dem SQL-Ressouce Kit (oder wars auf der Tools CD, ich weiß es nicht mehr genau).
Mit diesem kannst du recht schnell sehen, wo der "Flaschenhals" ist (einfach nach "Elapsed Time (ms)" absteigend sortieren).

Ist der 2. (schlankere) Import auch so Prozessorlastig?

Re: Performanceproblem mit Datenimport

25. September 2009 10:13

Bim Import der kleinen Datei ist die Prozessorauslastung zwar auch bei 100%. Jedoch liegt die Beanspruchung der Finsql.exe nur bei ca. 50% und die vom Sqlserver auch bei ca 50%. Bei der großen Datei beansprucht bereits die Finsql.exe 99%. Die große Artikeldatei ist 90MB groß und die kleinere 44MB. Hab auch schon die große Datei gesplittet, brachte auch keinen Performanceschub.

Re: Performanceproblem mit Datenimport

25. September 2009 12:06

fiddi hat geschrieben:Hast du in deiner Datenbank schon Clustered Indexe vergeben (einige 5er NAVs machen das automatisch)?
...
Des weiteren solltest du prüfen, wie groß dein Transaktion-Log ist, das wird bei so einem Import nicht gerade kleiner (so 3-4 GB frei dürfens bei der Datenmenge schon sein und wenn automatisch vergrößern, dann richtig (500MB- 1GB) und nicht in 10MB oder 10% Schritten.

NACHTRAG:
Was du wahrscheinlich am schnellsten prüfen kannst: Lass den Dataport mal direkt auf dem SQL- Server oder auf einem mit GBit- Ethernet angeschlossenen Rechner laufen. :!: :!:


Ich möchte dir Fiddis Beitrag nochmal ans "Herz" legen:
1. Hast du die Option den Import dirtekt auf dem Server zu Testen, damit könntest du folgendes ausschließen:
Das dein Rechner evtl. der Flaschenhals (Prozessor / Speicher / Netzwerk) ist.

2. Wenn du 1. Datei Importierst, welche Tabellen werden "angefasst" bzw. gefüllt?

3. Wen ich es richtig weis, hat das "Wiederherstellungsform" (Recovery Model) auch Einflus auf die Geschwindigkeit (ich kein SQL-Profi), diese auf "Einfach" stellen.

Diesen Beitrag gefunden:
4,5 Mio. Posten Importieren

Also alle Key´s, deaktivieren (danach das aktivieren nicht vergessen)

Re: Performanceproblem mit Datenimport

25. September 2009 12:29

Wenn Server und Client am Rad drehen, d.h. dauernd über 50 % Auslastung sind, stimmt da was mit der Programmierung nicht.

Da der Client unter Vollast läuft, vermute ich, das in einem Trigger Daten sequenziell durchlaufen werden, was dazu führt, das der Server eine Unmenge an Requests bearbeiten muss, weshalb auch der beschäftigt ist.

Mach mal eine Importdatei mit genau einem Artikel, importiere diese Datei und lasse bei dem Import den SQL-Profiler mitlaufen. Er sollte dir alle Zugriffe auf die Datenbank protokollieren. Werden bestimmte Daten besonders oft, bzw. aus einzelnen Tabellen besonders viele Datensätze angefordert, solltest du dort anfangen zu optinieren.

Gruß, fiddi

@mikka, war das mit meinem Nicknamen Absicht, oder hast du Probleme mit dem lesen :!: :?: :-?

Re: Performanceproblem mit Datenimport

25. September 2009 13:02

fiddi hat geschrieben:@mikka, war das mit meinem Nicknamen Absicht, oder hast du Probleme mit dem lesen :!: :?: :-?


Oh mann, dickes Sorry. Das war ein ganz blöder Schreibfehler. Ich habe es geändert, muß aber gestehen Schmunzeln mußte ich schon (du wohl weniger oder?)
:greenarrow: Was das schreiben angeht, klappt das manchmal nicht so :roll: