PDA

View Full Version : Zugriff mit sql wirklich schneller



Seiten : [1] 2

dibe
08-08-23, 14:49
Guten Tag,
hier wird ja häufiger erwähnt das das lesen einer Datei mit SQL besser / schneller / moderner als mit setll/read ist.
Modern und besser ist uns egal, schneller ist natürlich super.

Wir haben nun ein Pgm erstellt, das zu verschiedenen Werten eines Datensatzes andere Infos aus anderen Dateien holt.

immer in dieser Art:
exec sql
set :Feld =(select Feld from datei where
f1='konstante' and f2 = :F3
and f3 between :xx and :yy )
end-exec

wobei die Where natürlich immer wieder anders aussieht

Ohne das wir es probiert haben aber ich denke, das die Laufzeit des Pgms deutlich länger ist, als wenn ich setll read + dow verwendet hätte.

Was denkt Ihr? Sql oder Setll read und ggf mal 1-5 Sätze überlesen?
(i.d.R. enthält die Where Bedingung ein ( f1 = :x or f3 = :y) oder ein between so das ein richtig guter LF für einen chain nicht geht.

Vielen Dank
Dietlinde Beck

Fuerchau
08-08-23, 15:14
In der Regel macht man einen

select f1, f2, f3, ...., fn
from mytable
where ...

Also genau dasselbe, wie im Ergebnis SETLL/READE oder CHAIN.
Wenn man es genau nimmt, führt man genau die Felder auf, die man benötigt.
Das hat den Vorteil, dass Datei/Table-Änderungen weniger problematisch sind.
Natürlich kann man auch einen "select * into : MyTableDS from mytable ..." verwenden, das macht das Programmieren nur einfacher.
Wenn du natürlich 200 Felder einzeln liest, wird es klarerweise langsamer, aber so sollte man nicht arbeiten.
Außer du hast eine superstarke Normalisierung der Datenbank vor (Stufe 5):
Jede Information wird nur mit einem (mehrfachen) Schlüssel gespeichert.
Das habe ich aber noch nirgends gesehen.

Das Lesen per SQL zu native ist kaum messbar, da Programmaufrufzeiten vernachlässigbar sind.
Und die Maschinen sind auch noch schneller als früher.
Interessant wird es dann eher bei komplexeren SQL's mit Join, Group by, was man in RPG nur schwer hinbekommt.

dibe
08-08-23, 15:22
Na ja, wenn ich mehr als ein Feld aus der Datei brauche, machen wir ein select into.
i.d.R brauchen wir aber nur ein Feld

Aber je Datensatz den wir verarbeiten jeweils aus 3-7 verschiednen Dateien.

BenderD
08-08-23, 16:35
... wie so oft: it depends. Für einen Einzelsatzzugriff (chain o.ä. auf eine einzelne Datei) ist SQL immer langsamer als RLA (egal was das IBM Marketing und seine Apologeten da behaupten).

Für das lesen eines Resultsets ist der SQL Zugriff bei entsprechendem Datenbankdesign (inklusive der entsprechenden Indexe) typischerweise schneller, typischerweise mit höherem Ressourcenverbrauch.

Was den Programmieraufwand angeht, ist SQL bei adäquater Vorgehensweise und ausreichender Qualifikation gegenüber dem zusammenklappern von Daten mit RLA deutlich im Vorteil.

D*B

PS: Bei dem skizzierten Beispiel sehe ich in der Vorgehensweise noch deutlich Luft nach oben.

Fuerchau
08-08-23, 16:44
Dann wäre auch interessant, ob die 3-7 Zugriffe nicht ebenso per Join-Query mit einem SQL durchführbar wären.
Und eure Dateien sind auch 1-Feld-Dateien + Key?

dibe
09-08-23, 08:14
Vielen Dank erstmal.
Nein die Dateien haben deutlich mehr Felder. Es geht um eine einmalige Auswertung über einen > 40 jahre alten, größtenteils noch aktiven Datenbestand. Da brauchen wir hier mal ein Datum und da mal ein Kennzeichen, das sich, je nach Art und alter des Basissatzes, mal so mal so ermitteln lässt.
Eine optimierung mit Index wäre sicher möglich wenn ich bis zu 4 neue Indexe auf die Dateien packe.
aber das dauert bei durchschnittlich 12 Mio Datensätze auch und lohnt für die einmalige Auswertung nicht. Das Datenmodel ist eigendlich gut!

Es geht mir auch nicht um diesen Fall, hier ist es nur aufgefallen!
Codiert ihr mitlerweile anstatt eines chain ein SQL: select into?

BenderD
09-08-23, 08:36
... Auswertungen wie diese und Subfiles gehören zu den reinen Lesezugriffen (ohne updates). Der SQL Weg hierfür ist, einfach skizziert:
- Ermittlung eines SQL Statements, das die benötigten Daten komplett liefert
- prepare enstsprechenden read only cursor (mit host variablen für einschränkende Bedingungen)
- Blockfetch (so 1000 Sätze oder mehr auf einmal in eine entsprechende dim Struktur)
- Optimierung durch anlegen von Indexen
Die Geschwindigkeit kommt hierbei primär durch die Ersetzung von mehreren Tausend Einzelzugriffen per RLA durch einen einzigen SQL Zugriff.
Vorhamdene Zugriffslogik, Daten per read und chain zusammen zu klappern, eins zu eins durch SQL zu ersetzen bringt keine Vorteile, kumuliert eher Schwächen.

Für Einmal Auswertungen hat die SQL Variante nach obigem Muster den Vorteil, dass man die Zugriffslogik vorab komplett testen kann (man sieht ja die Daten vorab). Die resultierende Laufzeit ist bei geringen Datenmengen (12 Mio Datensätze sind nicht viel! Viel fängt heute bei mehreren 100 Mio an) nebensächlich.

D*B

Fuerchau
09-08-23, 08:39
Da du ja derzeit mit SETLL/READE wohl auf einer LF arbeitest, sollte das als Index ja genügen;-).
Und bei 12 Mio. Zeilen würde ich mir keine Gedanken über einen zusätzlichen Index machen.
Das dauert je Index keine 30 Sekunden.

dibe
09-08-23, 09:44
@D*B
Ich kann die Daten nicht wirklich lesbar, und performant mit EINEM Sql verknüpfen
Dazu wären etliche Case Bedingungen zu gestalten.

Ich lese mit setll/read eine Datei durch und muß aus zig verschiedenen Datein Einzelwerte dazu holen.
Welcher Wert, mit welcher Bedingung und welche alternative bei nicht gefunden ist individuell vom Alter des Satzes und der Art des Basissatzes abhängig.

Vermutlich aus Ihrer Sicht Murks, so haben Sie sich ja schon öfter ausgedrückt.
Aber für die Aufgabe unerlässlich. Und das 'vereinheitlichen' aller Daten wäre, bei der Masse der Programme hier, ein nicht zu unterschätzender Aufwand.

Bitte lassen sie uns doch einfach die Performance
set :Feld = (select x from x where z...) VS
Setll, dou, read, if z = ... leave, enddo bei max 5 zu überlesenden Sätzen
sprechen

Und da ist, wenn ich Sie vorab richtig verstanden habe der RLA Zugriff doch schneller, da nicht der SQL Rucksack aufgebaut wird?


@Fuerchau
keine 30 Sekunden?
Ich rede von > 40 Minuten!

Danke
DiBe

BenderD
09-08-23, 10:04
@Murks: ich rede gerne Klartext, das ist verständlicher und hat sich bei Schulungen und Vorträgen bewährt. Den meisten Murks findet man bereits vor, man sollte sich bemühen den Murks nicht noch größer zu machen, dafür braucht man einen geschärften Blick, was Murks ist.

Zurück zur Problemstellung:
Wenn Datensätze aus mehreren "Basisdateien" zusammengeführt werden sollen, landet man beim Union der ist niemals wirklich schnell. Für read only ist da am effektivsten die Daten im ersten Schritt in einer temporären Tabelle zu sammeln und dann auf diesen Bestand weiter zu machen.
Das zufügen von fehlenden Feldern kann man dann mit erledigen, ob man da case oder coalesce ausreicht, hängt von den Daten ab.

Wenn nichts "überlesen" wird, ist RLA schneller und vor allem Ressourcen schonender. Solange SQL nichts blocken kann (auch hinter den Kulissen) ist RLA im Vorteil.

Wenn bei euch ein Index Aufbau über 12 Mio Sätze 40 Minuten braucht, dann habt ihr - aus heutiger Sicht - ein ernsthaftes Problem: entweder völlig unzureichende Hardware oder einen Softwaredefekt oder eine völlig vermurkste Konfiguration des Systems (Subsysteme, Speicherpools...)

mfg

und nix für Ungut für das ein oder andere harte Wort

Dieter Bender