PDA

View Full Version : Performance-Pobleme SQL-Select - Jobaufrufstapel hängt bei QDBGETMQO



berndl
18-03-14, 14:57
Hallo zusammen,

wir suchen seit 2 Tagen an einem seltsamen SQL-Performance-Problem und sind ziemlich ratlos, wo wir weitersuchen können.

System V7R1
PTF MF50684 ist seit 10.03.2011 permanent angelegt (scheint irgendetwas damit zu tun zu haben)

Aus ILE-RPG setzen wir dynamische SQLs ab. Die SQLs sind jeweils aus Performancegründen auf ein Trefferlimit von 200 Records beschränkt, welches der Benutzer aber übersteuern kann. Das SQL sieht verkürzt folgendermassen aus:

SELECT * FROM TAB1 FETCH FIRST 200 ROWS ONLY

Seit der letzten Migration unserer produktiven DB auf das neue System, sind die Antwortzeiten bei 200 Records ca. 10 - 15 Minuten (die gelieferte Ergebnismenge stimmt). Wird dieses Limit auf eine andere Zahl (z. B. 199 oder 201) geändert, ist das Verhalten normal (ca. 0,5 Sekunden bis Anzeige inkl. Clientlogik). Wird das SQL über den Greenscreen (STRSQL) oder System-i-Navigator abgesetzt, ist die Antwortzeit im Millisekundenbereich.

Während dieser 10 - 15 Minuten geht die CPU-Last des Jobs über 200 %. In den offenen Dateien sind keine Lesezugriffe nachvollziehbar und im Joblog wird trotz gestarteten Debug (STRSRVJOB + STRDBG) nichts protokolliert. Richtiges Debuging ist auf der Maschine im Moment leider (noch) nicht möglich.

Im Aufrufstapel sind die folgenden Programme (in dieser Reihenfolge eingetragen:
Programm___LIB___Anweisung__Prozedur
....
RISGSS16___RI2IPGM01___5279___RISGSS16 (SQL absetzendes ILE-RPG-Programm)
QSQROUTE___QSYS___12449___QSQROUTE
QSQRUN2___QSYS___11769___SQL_Fetch
QSQRUN2___QSYS___13964___F_GETNEXTL
QSQRUN2___QSYS___19733___F_GETBLK
QDBGETMQO___QSYS___2899___QDBGETMQO

Was macht QDBGETMQO?
Hat jemand einen Tipp zum weiteren Vorgehen?

Herzlichen Dank schon mal im Voraus


P.S. hier noch das komplette SQL (läuft schnell und fehlerfrei):
SELECT DISTINCT GES.*
FROM RIPGES AS GES
JOIN RIPGFG AS GFG ON GES.GESHID = GFG.GESHID
JOIN RIPSRS AS SRS ON GFG.FIRHID = SRS.FIRHID AND GFG.STEHID = SRS.STEHID
JOIN RIPGSB GSB ON GES.GESHID=GSB.GESHID AND GSB.PFAHID= 15 AND GSB.PERID= 3000003
AND GSB.GSBZOAB <= CURRENT_DATE AND GSB.GSBZOBIS >= CURRENT_DATE AND GSB.RIFISTGEL = '0'
WHERE
SRS.SRSGUEAB <= CURRENT_DATE AND SRS.SRSGUEBIS >= CURRENT_DATE AND GFG.FIRHID = SRS.FIRHID
AND GFG.STEHID= SRS.STEHID AND GFG.GFGSTS='5' AND SRS.RIFISTGEL ='0'
AND GFG.RIFISTGEL ='0' AND GES.RIFISTGEL ='0'
AND ((GFG.PFAHID = 0 AND GFG.PERID =0 ) OR (GFG.PFAHID=SRS.PFAHID AND GFG.PERID=SRS.PERID))
AND SRS.PFAHID = 15 AND SRS.PERID = 3000003 AND GES.FIRHID=102709 AND GES.GGPHID=100183
AND (GESABSDAT ='0001-01-01' OR GESABSDAT IS NULL)
ORDER BY GES.GESJAHR DESC, GES.GESNBR DESC
FETCH FIRST 200 ROWS ONLY;

andreaspr@aon.at
18-03-14, 15:23
Hallo,

sicher dass das SQL Statement bei der Änderung des Limits !=200 genau das gleiche ist (bis auf das Limit)?
Keine andere Sortierung oder der gleichen?
Das ist schon sein sehr ungewöhnliches verhalten wenn es so dramatisch am Limit liegt.

STRSQL und der Navigator haben sowieso ihre eigene Limits die da überschrieben werden.
Man glaubt es wurde alles gelesen, dabei werden die restlichen Sätze erst beim hinunter scrollen gelesen.

Hast du schon probiert das ganze mit dem DB-Monitor zu analysieren?

lg Andreas

BenderD
18-03-14, 15:33
... die Angaben sind ein wenig konfus (das SQL sieht verkürzt... dann doch ganz anders aus...). Sieht für mich nach einem kaputten package aus. Ich würde erst einen recreate des Programms versuchen und ansonsten Software defect reklamieren.

D*B

berndl
18-03-14, 16:13
erstmal danke für die schnellen Antworten!

Das SQL ist genau identisch - inkl. Leerzeichen. Der Benutzer gibt die Suchkriterien jeweils ein und daraus wird das Select-Statement generiert.
Hab dar Programm aus einer anderen LIB kopiert, wo wir das Prolem nicht haben (andere Daten) -> gleiches Verhalten.
Was ist mit kaputten Package gemeint? Die Programme werden jeweils auf einem anderen System kompilliert (CRTSQLRPGI ...).
Der DB-Monitor (=SQL-Performance-Monitor?) zeigt mir keine hilfreichen Informationen. Dort sehe ich lediglich, dass die Fetch-Opreration "FETCH SQL_EXTRACT INTO DESCRIPTOR : H" eine Runtime von 280.270424 Sekunden hat. Die gleiche Operation für die anderen Row-Limite aber nur 0.000104 Sekunden. Beide Male gibt's die gleiche Ergebnismenge: 0 Treffer!
Die detaillierte Auswertung mit VisualExplain sagt mir darüber hinaus nichts mehr - da fehlt das Detailwissen.

Fuerchau
18-03-14, 16:22
Das mit dem Limit kann schon mal sein, da SQL intern blockt.
Da kann schon mal 1 Satz mehr zu einem 2. Block und somit zu einem erneuten DB-Zugriff führen.
Der DBGETMQ erstellt temporär eine Ergebnistabelle (MaterializedQueryTable) was massiv auf fehlende Indizes hindeutet.
Wenn das mit einer anderen Daten-Lib läuft, ist dort die Datenmenge anders was zu anderen Optimierungszielen führt und somit zu anderem Verhalten.

Ggf. hilft ein "Optimize for firstio" (oder so ähnlich), was dann beim Weiterblättern nicht hilft.
Ich musste bei V7R1 schohn änliches feststellen.

BenderD
18-03-14, 16:27
Was ist mit kaputten Package gemeint? Die Programme werden jeweils auf einem anderen System kompilliert (CRTSQLRPGI ...).

Das Package ist Teil des Programm Objektes, ich würde das möglichst mal auf dem Echtsystem erstellen, zumindest neu deployen.

berndl
18-03-14, 17:25
okay, das klingt schon beruhigender - dachte das Q-DBG-ETMQO hat irgendwas mit Debug zu tun.
Dann deployen wir das Ganze nochmals und prüfen wieder die ganzen Indizes...
Danke, meld mich wieder nach der Indexanalyse

berndl
24-03-14, 06:28
Nach Rücksprache mit IBM haben wir das Problem jetzt gelöst. Das Verhalten lag an einer Einstellungen im QAQQINI:
REOPTIMIZE_ACCESS_PLAN war bei uns auf *ONLY_REQUIRED gesetzt - diese Einstellung wurde von der "alten" Maschine übernommen und nicht hinterfragt. Seit der Wert auf *DEFAULT steht, ist auch die Performance für 200 Datensätze okay.
Danke für eure Hilfe.

BenderD
24-03-14, 07:32
... das sind ganz grundsätzlich Einstellungen an denen niemals global gedreht werden sollte!!!