Anmelden

View Full Version : Embedded SQL - Performance-Probleme



Seiten : 1 [2] 3

Fuerchau
27-08-04, 09:11
Gut, schauen wir uns die Details mal an:

Dein Update scheint mir da weniger ein Problem zu sein, da 3 ms doch sehr schnell ist, also ca. 333 Updates pro Sekunde möglich sind.

Dass dein Insert ca. das doppelte benötigt ist auch verständlich, da dieser nicht nur den Insert sondern auch einen Select enthält. Jeder ca. 3 ms, entspricht immer noch ca. 166 Inserts bzw. 333 Operationen pro Sekunde.
Unter der Berücksichtigung, dass für jeden SQL folgendes abläuft:
1. Die Syntax geprüft
2. Die Datei über die LIBL ermittelt werden muss
3. Jedes Feld geprüft wird, ob es a) vorhanden ist und b) der Wert zum Typ passt
4. Jede Menge interne Call's (sind auch Disk-IO, falls gepaged wurde) ablaufen
Dann finde ich das immer noch verdammt schnell !

Nun betrachte, was auf deinem System noch so läuft:

Wieviele Job's sind gleichzeitig aktiv ?
Wievele Updates/Inserts laufen in diesen noch parallel ?

Dass der einzelne Job da RELATIV lange benötigt, heißt nicht, dass dieser ein Engpass ist !!!

Zur weiteren Analyse schau mal über WRKACTJOB mit F11 auf die Sicht "Abgelaufene Daten". In der Spalte "AuxIO" kannst du über den Messzeitraum (zwischen F10 und F5 ergibt oben die abgelaufene Zeit) sehen, wieviele IO's pro Job gelaufen sind.
Mit F16 kannst du die Spalte sortieren, so dass die größten Werte oben stehen.

Bei mir sehe ich z.B., dass ein Batchprogramm gerade 13000 IO's in einer Minute erzeugt.

Dann betrachte per WRKSYSSTS die Gesamtbelastung:
In den DB/Nicht-DB-Spalten siehst du die Anzahl IO's pro Sekunde mit jeweils 4KB (1 Block).
DB-Seiten sind Datenbankobjekte (PF's, LF's, usw.)
Nicht-DB-Seiten sind z.B. Programmobjekte.
Spalte "fehl." sind Seiten (4K), die aus dem Pool verdrängt und neu gelesen werden
Spalte "geles" sind Seiten (4K), die noch nicht im Pool waren.

Wenn das noch nicht ausreicht, schau auch noch WRKDSKSTS nach.
Zu jeder Spalte gibt es eine Hilfe-Beschreibung (ALT-F1).

Wer jetzt noch behauptet, dass 3ms für Update und 6 ms für Insert langsam sind, der sollte sich mal die Plattenphysik anschauen.
Durchschnittliche Zugriffszeit beträgt pro Platte immer ca. 9-11 ms (je nach Plattentyp).

Die Anzahl der Platten im System und nicht die Größe der Platten ist entscheidend !
Da es nun 8, 16 und auch nun auch 32GB-Platten gibt ist (was Disk-IO angeht) ein System mit 8 * 16GB mit 11ms schneller als mit 4 * 32GB mit 9ms (oder heute PC's mit 120, 160 oder gar 200GB).
Es stehen einfach mehr parallele Zugriffsarme zur Verfügung !

Ganz krass hatte ich einen Kunden, der früher mit 10 * 6GB nun mit 2 * 32GB über Disk-IO-Engpässe stöhnt. Dies ist nur mit mehr Platten oder extrem vergrößertem Hauptspeicher wieder zu beschleunigen, dass ist aber zu teuer, nun stöhnt er lieber.

MrBonZai
27-08-04, 09:15
Wenn Du für 30 Schreiboperationen 15 sec. brauchst, dann sind das pro update 0,5 sec. sprich 1/2 sec., das ist allerdings schon viel und deutet auf fehlende Zugriffspfade oder auf ernsthafte Ressourcenengpässe hin.

du hast recht... war ein kompletter Irrtum meinerseits!
es sind 0.5 Sekunden und nicht 5 ms... sorry.

Benötigt ein INSERT einen speziellen "Zugriffspfad"?
oder kann ich einen speziellen Zugriffspfad erzwingen?

oder ist das nur bei SELECT so?

ein Update braucht derzeit ca. 0.3 Sekunden... ein Insert 0,5 bis 0,6 Sekunden.
wie kann ich denn bei Update/Select einen Zugriffspfad erzwingen so dass ich mir wenigstens diese Zeit sparen kann?

BenderD
27-08-04, 09:30
Hallo Alex,

nachdem wir von denselben Zeiten ausgehen: woher kommen diese Angaben (die 0,3 und 0,5 sec)???

mfg

Dieter Bender


du hast recht... war ein kompletter Irrtum meinerseits!
es sind 0.5 Sekunden und nicht 5 ms... sorry.

Benötigt ein INSERT einen speziellen "Zugriffspfad"?
oder kann ich einen speziellen Zugriffspfad erzwingen?

oder ist das nur bei SELECT so?

ein Update braucht derzeit ca. 0.3 Sekunden... ein Insert 0,5 bis 0,6 Sekunden.
wie kann ich denn bei Update/Select einen Zugriffspfad erzwingen so dass ich mir wenigstens diese Zeit sparen kann?

Fuerchau
27-08-04, 10:14
Einen Zugriffspfad "erzwingen" kann man leider nicht.
Für einen Insert benötigt man keinen Zugriffspfad, wohl aber für einen "update ... where" als auch für einen "select ... where" der ja nun Bestandteil deines Insert's ist.

Ich würde auch mal prüfen, wieviele Sätze denn beim Update immer betroffen sind !
Ist es denn tatsächlich immer nur 1 Satz oder sind es ggf. auch mal mehrere oder ganz viele ?

Du kannst natürlich (auch per SQL) prüfen, ob es einen Zugriffsweg gibt, oder alternativ einfach einen Index (per Create Index) erstellen.
Verpasse einen eindeutigen Namen (max. 128 Stellen) aus z.B. den Feldnamen der Where-Klausel zusammengestellt und erstelle den Index.
Wird der Befehl abgewiesen, ist er halt schon da (zugegeben nicht besonders schön, funktioniert aber).
Insbesonders für das Feld PSLFNR einen absteigenden Index, da ja immer nach dem größten Schlüssel gesucht wird.

Als zusätzliche Alternative bietet sich SQLCLI an, da hier bei Parameter-Markern "?" auch Character-Felder mittels SQLPutParm() verwendet werden können.
Hier kann man dann auch eher mit SQLPrepare arbeiten, über eine interne Liste feststellen, ob der SQL-Befehl schon mal prepared wurde und sich somit Zeit und Performance sparen.

Fuerchau
27-08-04, 10:17
Ach ja,

läuft deine Schnittstelle im Dialog oder Batch ?
Wie sehen deine CPW-Definitionen für Dialog und Batch aus ?

Bei SQLCLI kann man die SQL's im Batch ausführen lassen !

MrBonZai
27-08-04, 10:39
nachdem wir von denselben Zeiten ausgehen: woher kommen diese Angaben (die 0,3 und 0,5 sec)???

ich habe zu Testzwecken, da die Performance so schlecht war ein Potokoll geschrieben, dass mittels Timestamp die Zeiten vor und nach dem SQL wegschreibt.
so habe ich das ganze Programm "analysiert" und der einzige wirkliche Knackpunkt scheint das SQL zu sein.

MrBonZai
27-08-04, 10:41
beim Update wird nur ein einzelner Satz upgedatet.



Als zusätzliche Alternative bietet sich SQLCLI an, da hier bei Parameter-Markern "?" auch Character-Felder mittels SQLPutParm() verwendet werden können.
Hier kann man dann auch eher mit SQLPrepare arbeiten, über eine interne Liste feststellen, ob der SQL-Befehl schon mal prepared wurde und sich somit Zeit und Performance sparen.
Was ist SQLCLI ? habe ich leider noch nie gehört.
wo finde ich Informationen darüber?

Das Programm läuft immer im Dialog.
was sind CPW-Definitionen?

BenderD
27-08-04, 10:47
Hallo Alex,

als nächstes würde ich erst mal mit STRDBMON (detail auswählen) oder Ooops Nerv den Job mit dem Database Monitor überwachen und dann in der Summary die durchschnittlichen und max Zeiten pro INSERT/UPDATE ermitteln und in den Details die teuersten Statements genauer ansehen mit den dazugehörigen Infos, was die Query Engine treibt. Zusätzlich interessant sind hier noch die Empfehlungen für Indexe.
Nächste Maßnahme wäre das rausloggen der gebastelten SQL Statements, soweit nicht bereits geschehen.
Die Verarbeitungszeiten Deiner Protokolle müssen mit den Logs konsistent und nachvollziehbar sein.
Wichtig ist auch, dass ein halbwegs aktuelles GRPPTF für die Datenbank installiert ist - ohne Group PTF funktioniert die Datenbank sowieso nicht seitdem es GRP PTFs für die DB gibt.

mfg

Dieter Bender


ich habe zu Testzwecken, da die Performance so schlecht war ein Potokoll geschrieben, dass mittels Timestamp die Zeiten vor und nach dem SQL wegschreibt.
so habe ich das ganze Programm "analysiert" und der einzige wirkliche Knackpunkt scheint das SQL zu sein.

Fuerchau
27-08-04, 12:33
Im Dialog kannst du dein Programm sicherlich debuggen (STRDBG).
Nach Ausführung des jeweiligen SQL's schau mal ins Joblog.
Die Datenbank schreibt dann jede Menge Meldungen über verwendete und empfohlene Zugriffspfade.
Lege dann einfach mal per STRSQL mit CREATE INDEX genau so einen Zugriffspfad an und wiederhole den Test mittels STRDBG.
Vergleiche dann die Meldungen des Joblogs mit den vorherigen.

SQLCLI ist ein C-Interface, dass ODBC-ähnliche Zugriffe auf Datenbanken unterstützt.

CPW sind die sog. Transaktionswerte, die IBM in Dialog und Batch aufgedröselt hat.
Zu erfragen bei IBM bzw. feststellbar durch Model und Prozessor.
Bei langlaufenden SQL's wird der Dialog häufig ausgebremst, was im Batch nicht der fall ist.

MrBonZai
06-09-04, 14:05
ich habe mitterweile mal beim Debug die Meldungen angeschaut...


Abfrageoptionsdatei kann nicht abgerufen werden.
Wartezeit für Abfrageoptimierungsprogramm für Datei NC6000 überschritten.
Zusätzliche Ursachencodes für Zugriffspfad verwendet.
Zugriffspfad der Datei NC6000 wurde von einer Abfrage verwendet.
ODP erstellt.
Datenumsetzung für Anweisung INSERT oder UPDATE erforderlich.
Offener Datenpfad (ODP) gelöscht.
1 Zeilen in NC6000 in TRZ90PD aktualisiert.


was ist denn mit Abfrageoptionsdatei gemeint?
eine F1 auf die Meldung bringt folgendes zu Tage:

Nachricht . . . : Abfrageoptionsdatei kann nicht abgerufen werden.

Ursache . . . . : Die Abfrageoptionen konnten aus Teildatei QAQQINI in Datei
QAQQINI in Bibliothek QUSRSYS aufgrund von Ursachencode 2 nicht abgerufen
werden. Ursachencodes und ihre Bedeutung:
2 - Datei QAQQINI in Bibliothek QUSRSYS wurde nicht gefunden.

damit kann ich nichts anfangen.

Auch die Meldung "Wartezeit für Abfrageoptimierungsprogramm für Datei NC6000 überschritten." ist mir schleierhaft.
Ich habe ALLE Key-Felder in korrekter Reihenfolge in meiner "Where"-Klausel.
Er hat im Endeffekt auch die korrekte LF (was in diesem Fall die PF ist) verwendet... Die Meldung erstaunt mich allerdings.


zudem habe ich Probleme mit "Datenumsetzung für Anweisung INSERT oder UPDATE erforderlich. "
dort wird das Feld BWOT angemeckert (BWOT ist 17 A)
Ich habe aufgrund dieser Meldung z.B. alpha-Felder mit der korrekten Länge angegeben z.B. anstatt bwot = 'test' in korrekter Länge bwot = 'test '
Die Meldung erscheint aber weiterhin, oder ist hiermit etwas anderes gemeint?

Gruss Alex