View Full Version : Expertenfrage zur Performance
Hallo,
ich habe folgendes Problem:
1. Ich soll anhand einer Nr. aus mehreren AS/400-Anwendungen Daten ermitteln und daraus eine Schnittstelle(Kopf und Positionen) erstellen. Zuerst ein Kopf- und ein Positionssatz und später ggf's noch mehrere Positionen, da nach der Übernahme evtl. noch Daten zur nr. erfaßt werden können. Die PF's der diversen Anwendungen befinden sich ggf's in unterschiedlichen Firmenbibliotheken(z.B. gibt es den Artikelstamm ARTPF den Bibliotheken Firm01, Firm02, usw...). Es handelt sich teilweise um ältere RPG II/III/400-Anwendungen und es liegen keine Sourcen vor(was aber auch nicht so wichtig ist). Bei den PF's handelt es sich teilweise um PF's mit einem Satzformat, mit mehreren Satzformaten, aber auch um Join-Files mit bis zu 10 PF's.
2. Diese Schnittstelle soll nach jeder eignescannten Nr. in einer Ascii-Datei auf einem Netzlaufwerk bzw. IFS zur Verfügung gestellt werden, da dass neue System eine PC-Software ist und sich dort die Daten abholt.
Da diese Schnittstelle inkl. der neuen Software später im Tagesgeschäft laufen soll und täglich 4-5.000 Tausend Kopfsätze und 20-30.000 Positionen übertragen werden sollen, suche ich dazu eine sehr performante Lösung um dies zu bewerkstelligen. Leider habe ich zur Zeit keine Möglichkeit zu testen, welche Zugriffs- und Übertragungsmethode mit dieser Datenmenge am schnellsten ist.
zu 1.:
Gibt es Performance-Einbußen zwischen RPG/400, ILE oder Free?
Ist es sinnvoll dies mit setll/reade bzw. chain zu machen? Geht es schneller, wenn ich nicht die Join-Files benutze, sondern programmintern je einen Zugriff auf die entspr. verknüpfte Datei mache? Sind Zugriffe auf eine mit usropn definierte Datei schneller oder kostet das open/close mehr performance(es gibt auch Dateien, die nur in einer Lib stehen)? Sind die Zugriffe mit embedded SQL schneller bzw. durch welche Angaben kann man SQL evtl. noch beschleunigen (kenne zwar SQL, bin jedoch kein Fachmann darin, wie man dort mit ein paar Tricks oder Kniffen SQL performanter laufen lassen kann)? Ist es sinnvoll die Dateien intern über ein CMD zu überschreiben(Bibliothekswechsel) oder sollte ich besser die Bibliotheksliste umstellen?
zu 2.:
welche Übertragung geht am schnellsten, per CPYTOIMPF, per CRTCSVF, ASCII-Datei über eigenes Prg erstellen und dann über ein CA-Tool(z.B. *.tto) übertragen oder gibt es da evtl. irgendwelche Tools, die ggf's schneller übertragen(wie z.B. in der Art CVTPFXLS oder ähnliche)
Mein erster Gedanke wäre jetzt:
Programmierung in Free;
SETLL/READE bzw. CHAIN machen(da ich nicht genau weiß, an welchem Rädchen man bei SQL drehen kann, damit es schneller geht als Reade/chain);
Join-File beibehalten bzw. neue Join-Files(wenn Dateien drin sind die ich nicht brauche) oder LF's mit Selcet/ommit;
PF's würde ich intern überschreiben, statt Lib-Liste zu ändern.
Übertragen würde ich die Datei per CPYTOIMPF
Ich bin aber für alle Tipps offen und dankbar, wie es evtl. schneller läuft bzw. ob es so wie gedacht sinnvoll ist.
Vorab schon einmal vielen Dank.
andreaspr@aon.at
23-08-10, 13:17
Mein erster Gedanke wäre jetzt:
Programmierung in Free;
SETLL/READE bzw. CHAIN machen(da ich nicht genau weiß, an welchem Rädchen man bei SQL drehen kann, damit es schneller geht als Reade/chain);
Join-File beibehalten bzw. neue Join-Files(wenn Dateien drin sind die ich nicht brauche) oder LF's mit Selcet/ommit;
Hi,
in Sql (falls man es einsetzen will) würde ich es so machen:
Je nachdem was du machen möchtest kannst du einen Sql-Cursor erstellen. Wenn du im Ablauf nur EIN chain machst, reicht meines erachtens auch ein Select sp1 Into :v1 From Tab1 where ...
Wenn du das gleiche chain öfters benutzt, kannst du den Sql-Cursor verwenden. (chain wäre dann ein Open Cursor & Fetch MyCursor Into :v1)
Ein Select ... Into ... ist nicht grad der schnellste weg um an Daten zu kommen.
Wenn du LFs mit Select/Ommit benützen möchtest, ist jedoch das chain besser, da diese LFs nur mit der alten Sql-Engine verarbeitet werden können.
Andernfalls in SQL einen Index oder View erstellen (ab 6.1 sogar bis zu einem gewissen Grad kombiniert)
Grundsätzlich gilt schon, dass ein einzelner Chain schneller ist als SQL. Wenn du direkt auf die LFs zugreifst ist das schneller als wenn SQL den besten Zugriffspfad erst ermitteln muss. Zumindest solange du nur einzelne Sätze einer Tabelle lesen gehst.
Sobald du jedoch eine große Anzahl an Sätzen verarbeiten musst schaut das Ganze wieder etwas anders aus. Denn die Erstellung des Zugriffspfades in SQL dauert nur ein paar Millisekunden. Da ist dann die Frage ob der Zugriffspfad nur ein paar mal erstellt werden muss oder 1 Mio mal. (Bei 1 Mio mal hat man sowieso einen Entwicklungsfehler).
Der Vorteil von SQL wäre, dass du später zb MQTs oder Indices erstellen kannst die dann gleich von SQL benutzt werden können. Bei chain usw. musst du von Anfang an Fix deine Zugriffspfade kennen und bestimmen.
Ich würde kein overlay verwenden nur um die LIBL auszutrixen, sondern die LIBL bzw. CURLIB entsprechen anpassen. Fehler lassen sich dadurch schneller und besser finden.
Hallo Andreas und vielen Dank schon mal.
schon wieder was dazu gelernt in SQL :-), aber in diesem spez. Fall werde ich es dann wohl per chain machen, da es fast immer nur ein chain ist und ich keine großen Datenmengen lesen muss.
Von den int. Dateiüberschreibungen bin ich eigentlich auch kein Fan, aber hier wird das standardmäßig so gemacht und wenn es jetzt keinen Grund gibt vom Standard abzuweichen(z.B. dass es schneller wäre per Lib-List-Änderung), wird das Abweichen vom Standard leider nicht so gerne gesehen.
Gruß,
Roland
andreaspr@aon.at
23-08-10, 18:48
Hi Roland,
welche OS-Version hast du? Ab 6.1.1 gibt es auch möglichkeiten eines temporären Filesystems im IFS. Das hat auch nette Performancevorteile.
lg Andreas
- das primäre ist erst mal nicht Performance: first do it right, then make it fast. Bei diesem Datenverhau wäre ich mit OVRDBF und CHGLIBL außerordentlich vorsichtig; falls da was in den Wind geht, suchst du dir den Wolf.
- am stabilsten ist da m.E. noch funktionales trennen, sprich jede Datei (in jeder Lib) hat eine eigene Zugriffsroutine, mit ausgefuchstem ILE Design könnten das auch mehrfache Aktivierungen deselben Programmes in unterschiedlichen ACTGRPs sein. Diese Variante wäre auch performanter, da in jedem Fall die unnützen close reopen Vorgänge wegfallen und bei statischem SQL keine Zugriffspfade neu berechnet werden müssen (was bei LIBL und OVRDBF Spielen immer erforderlich ist).
- SQL oder RLA ist hier (wie meist!!!) Pille Palle, die UNterschiede liegen unterhalb des Grundrauschens einer Anwendung, was hier eher was bringen könnte, ist caching (hängt aber von der Anwendung ab, ob das geht)!.
- zeit kritisch wird die Erzeugung der ASCII Files, mit Abstand am schnellsten ist hier das direkte erzeugen der ASCII Files mit C APIs (gibt es was auf meiner Freeware Seite), wenn alles in einen großen Datenkompost geworfen werden soll, muss man sich Gedanken um Synchronisation machen, damit da kein Häcksel entsteht.
D*B
Hallo,
ich habe folgendes Problem:
1. Ich soll anhand einer Nr. aus mehreren AS/400-Anwendungen Daten ermitteln und daraus eine Schnittstelle(Kopf und Positionen) erstellen. Zuerst ein Kopf- und ein Positionssatz und später ggf's noch mehrere Positionen, da nach der Übernahme evtl. noch Daten zur nr. erfaßt werden können. Die PF's der diversen Anwendungen befinden sich ggf's in unterschiedlichen Firmenbibliotheken(z.B. gibt es den Artikelstamm ARTPF den Bibliotheken Firm01, Firm02, usw...). Es handelt sich teilweise um ältere RPG II/III/400-Anwendungen und es liegen keine Sourcen vor(was aber auch nicht so wichtig ist). Bei den PF's handelt es sich teilweise um PF's mit einem Satzformat, mit mehreren Satzformaten, aber auch um Join-Files mit bis zu 10 PF's.
2. Diese Schnittstelle soll nach jeder eignescannten Nr. in einer Ascii-Datei auf einem Netzlaufwerk bzw. IFS zur Verfügung gestellt werden, da dass neue System eine PC-Software ist und sich dort die Daten abholt.
Da diese Schnittstelle inkl. der neuen Software später im Tagesgeschäft laufen soll und täglich 4-5.000 Tausend Kopfsätze und 20-30.000 Positionen übertragen werden sollen, suche ich dazu eine sehr performante Lösung um dies zu bewerkstelligen. Leider habe ich zur Zeit keine Möglichkeit zu testen, welche Zugriffs- und Übertragungsmethode mit dieser Datenmenge am schnellsten ist.
zu 1.:
Gibt es Performance-Einbußen zwischen RPG/400, ILE oder Free?
Ist es sinnvoll dies mit setll/reade bzw. chain zu machen? Geht es schneller, wenn ich nicht die Join-Files benutze, sondern programmintern je einen Zugriff auf die entspr. verknüpfte Datei mache? Sind Zugriffe auf eine mit usropn definierte Datei schneller oder kostet das open/close mehr performance(es gibt auch Dateien, die nur in einer Lib stehen)? Sind die Zugriffe mit embedded SQL schneller bzw. durch welche Angaben kann man SQL evtl. noch beschleunigen (kenne zwar SQL, bin jedoch kein Fachmann darin, wie man dort mit ein paar Tricks oder Kniffen SQL performanter laufen lassen kann)? Ist es sinnvoll die Dateien intern über ein CMD zu überschreiben(Bibliothekswechsel) oder sollte ich besser die Bibliotheksliste umstellen?
zu 2.:
welche Übertragung geht am schnellsten, per CPYTOIMPF, per CRTCSVF, ASCII-Datei über eigenes Prg erstellen und dann über ein CA-Tool(z.B. *.tto) übertragen oder gibt es da evtl. irgendwelche Tools, die ggf's schneller übertragen(wie z.B. in der Art CVTPFXLS oder ähnliche)
Mein erster Gedanke wäre jetzt:
Programmierung in Free;
SETLL/READE bzw. CHAIN machen(da ich nicht genau weiß, an welchem Rädchen man bei SQL drehen kann, damit es schneller geht als Reade/chain);
Join-File beibehalten bzw. neue Join-Files(wenn Dateien drin sind die ich nicht brauche) oder LF's mit Selcet/ommit;
PF's würde ich intern überschreiben, statt Lib-Liste zu ändern.
Übertragen würde ich die Datei per CPYTOIMPF
Ich bin aber für alle Tipps offen und dankbar, wie es evtl. schneller läuft bzw. ob es so wie gedacht sinnvoll ist.
Vorab schon einmal vielen Dank.
Sorry, dass ich erst jetzt antworte, hatte gestern und heute Probleme mit einem eindeutigen Key, der leider in der Praxis doch nicht so eindeutig war wie er theoretisch sein sollte...
Danke erstmals für die Antworten.
@andreas
Momentan ist leider noch 6.1.0 im Einsatz.
@Dieter
Das stimmt wohl, zuerst muss es überhaupt mal laufen, bevor man dem Programm dann Beine machen kann ;-). Aber wie immer fehlt die Zeit und deshalb wollte ich gleich alles von Anfang an performant machen. Ich war gerade eben auf Deiner Freeware-Seite. Da gibt es ja jede Menge interessanter Tools. Das mit den Aktivierungsgruppen ist eine gute Idee, kenne mich damit zwar auch noch nicht so richtig gut aus, aber das werde ich mir Morgen mal genauer anschauen und ausprobieren. Heißt das, dass ich in einer Aktivierungsgruppe, die gleiche Datei in unterschiedl. Lib's gleichzeitig öffnen kann?
Meintest Du "Übertragung mit Java..." oder "Schreiben in Streamfiles"? Bei "Übertragung mit Java..." hab ich das Problem, dass ich nicht weiß, was ich mit den *.java machen muss. Von Java weiß ich bis jetzt leider nur, dass es nicht nur eine Insel ist und etwas mit Klassen zu tun hat. C sagt mir da schon eher was. Naja, die beiden Bücher die ich dazu zu Hause hab sind leider zusammen mit dem C#-Buch am verstauben. Die Tage haben einfach zu wenig Stunden... Vielen Dank nochmals für die Freeware.
mit den Aktivierungsgruppen kann man erreichen, dass dasselbe Programm gleichzeitig mehrfach geöffnet ist und eines der aktiven Programme dann Firma1 verarbeitet und ein anderes Firma2 und...
wenn das für dich aber Neuland ist, würde ich das in dem Rutsch erst mal lassen - keep it simple! wichtig ist klare Modularisierung (an einem Riesenschinken kann man nix optimieren ohne das Risiko das was anderes umfällt).
Das erstellen der Streamfiles passiert im RPG mit C-APIs, den OUTSTREAM solltest du ja gefunden haben, den kann man da fertig als Komponente verwenden.
D*B,
dem sich bei Datenbank und LIBL immer alles umdreht (erst kauft man eine Datenbank mit referentieller Integrität und allem F und F und dann ist es einem Wurcht wenn die Aufträge aus einem anderen Schema wie die Kunden kommen...)
Sorry, dass ich erst jetzt antworte, hatte gestern und heute Probleme mit einem eindeutigen Key, der leider in der Praxis doch nicht so eindeutig war wie er theoretisch sein sollte...
Danke erstmals für die Antworten.
@andreas
Momentan ist leider noch 6.1.0 im Einsatz.
@Dieter
Das stimmt wohl, zuerst muss es überhaupt mal laufen, bevor man dem Programm dann Beine machen kann ;-). Aber wie immer fehlt die Zeit und deshalb wollte ich gleich alles von Anfang an performant machen. Ich war gerade eben auf Deiner Freeware-Seite. Da gibt es ja jede Menge interessanter Tools. Das mit den Aktivierungsgruppen ist eine gute Idee, kenne mich damit zwar auch noch nicht so richtig gut aus, aber das werde ich mir Morgen mal genauer anschauen und ausprobieren. Heißt das, dass ich in einer Aktivierungsgruppe, die gleiche Datei in unterschiedl. Lib's gleichzeitig öffnen kann?
Meintest Du "Übertragung mit Java..." oder "Schreiben in Streamfiles"? Bei "Übertragung mit Java..." hab ich das Problem, dass ich nicht weiß, was ich mit den *.java machen muss. Von Java weiß ich bis jetzt leider nur, dass es nicht nur eine Insel ist und etwas mit Klassen zu tun hat. C sagt mir da schon eher was. Naja, die beiden Bücher die ich dazu zu Hause hab sind leider zusammen mit dem C#-Buch am verstauben. Die Tage haben einfach zu wenig Stunden... Vielen Dank nochmals für die Freeware.
Hallo,
das Programm wird aus unterschiedl. Firmenumgebungen aufgerufen, daher sollte ja durch die Umwandlung mit Akt.-Gruppe *caller die Lib-Liste prinzipiell passen. Aus der Firmenumgebung bekomme ich ca. 80% der Daten, die anderen 20% sind abhängig von Parametern. Z.B.: wenn Parm1=A ist, soll das firmenspezifische Bezeichnungsfeld1 mit dem firmenübergreifenden Bez.-Feld aus LibA überschrieben werden, bei B aus LibB usw....
Den Outstream habe ich gefunden, Danke.
Ich habe heute zufällig ein Programm gefunden, dass ich für die Übertragung nur leicht modifizieren müßte(cpytopcd und ftp) und in dem schon Log+Errorhandling usw... vorgesehen ist.
Weiß jemand, ob die Übertragung viel langsamer wäre als per Streamfile?
CPYTOPCD ist nicht mehr empfehlenswert da das IFS /QDLS verwendet wird.
QDLS kann max. 8.3-Namen und unterstützt keine CCSID.
Besser ist auf jeden die Streamfile-Lösung mit einer Datei im IFS /Home.
Ach ja, stimmt. Danke. Das hätte ich eigentlich wissen müssen, hatte damit ja schon mal ein Problem als ich dort jemandem was reinstellen sollte und der Dateiname in Kombination mit dem Timestampfeld zu lang war...