|
Mehr Performance! Tuning von APEX-Anwendungen - Teil 1: Tracing, Analyse und Diagnose
Performance ist bei APEX-Anwendungen immer wieder ein Thema - je mehr
Nutzer mit einer APEX-Anwendung arbeiten, desto wichtiger ist es, dass
die Anwendungsseiten schnell und flüssig dargestellt werden. In diesem und
einigen der nächsten Community-Tipps stellen wir
einige Ansätze zum Performance-Tuning von
APEX-Anwendungen vor. Der erste Teil beschäftigt sich vor allem mit
der Diagnose von Performanceproblemen.
Wie findet man heraus, welche SQL-Abfragen problematisch sind
und wie lassen sich Details zu deren Ausführung ermitteln? Dazu werden die
in APEX eingebauten Möglichkeiten vorgestellt, aber auch auf Möglichkeiten
in SQL*Plus oder dem Oracle Enterprise Manager eingegangen.
Die kritische APEX-Komponente identifizieren: #TIMING#
Vor allem wenn mehrere Berichte auf einer Seite enthalten sind, sollte
man zuallererst herausfinden, welcher Bericht wieviel Zeit benötigt - das
die am längsten laufenden werden dann als erstes angegangen.
Hierfür ist das Schlüsselwort #TIMING#,
welches in den Regions-Footer gesetzt
werden kann, sehr hilfreich. Abbildung 1 zeigt eine APEX-Anwendungsseite
mit drei Berichten und den Angaben zum Zeitverbrauch, die mit dem
#TIMING#
Schlüsselwort ausgegeben wurden.
Abbildung 1: APEX-Anwendungsseite mit Informationen zu verbrauchter Zeit (#TIMING#)
Es ist deutlich zu erkennen, dass der Bericht oben rechts (Produkte) die
meiste Zeit verbraucht. Einem Bericht liegt stets eine SQL-Abfrage als
Datenquelle zugrunde - im Beispiel ist das die folgende ...
APEX Debugging
Eine weitere wichtige Informationsquelle ist das APEX-Debugging. Sie erreichen es
mit dem Link Debug in der Developer Toolbar unterhalb der Anwendungsseite oder
mit dem Debug-Schalter in der Seiten-URL (Abbildung 2).
Abbildung 2: APEX-Anwendungsseite mit Debug-Informationen
Wie in Abbildung 2 erkennbar ist, werden im Debug-Modus die einzelnen Prozeßpunkte
(samt evtl. auftretender Fehlermeldungen) und eine Zeitinformation angezeigt. Im Gegensatz
zu #TIMING# können Sie über die Debug-Funktion auch die Laufzeit der onLoad-Seitenprozesse
messen und langlaufende Kandidaten identifizieren. Übrigens: In APEX 4.0 hat sich das
Debugging grundliegend verändert. Es wird in einem interaktiven Bericht dargestellt, so dass
Sie ganz bequem auswerten können.
Abbildung 2a: Debugging-Informationen in APEX 4.0 anzeigen
Diagnose mit SQL*Plus
Schauen wir uns nun nochmals die konkrete SQL-Anweisung des langlaufenden Berichts
an. Erfahrene APEX-Entwickler erkennen sofort, dass dieses SQL nicht so günstig
formuliert ist. Ein erster Blick gilt dem Ausführungsplan, den Sie mit Werkzeugen
wie dem SQL Developer anzeigen können - im folgenden sei aber die Vorgehensweise
in SQL*Plus gezeigt. SQL*Plus kennt das schon etwas ältere set autotrace-Kommando, welches nicht
nur einen Ausführungsplan angibt, sondern auch Informationen zu gelesenen Blöcken
ausgeben kann. Hat man ein fertiges SQL-Kommando und kennt man auch alle Parameter,
ist dies ein sehr wertvolles Hilfsmittel.
Um das SQL*Plus Autotrace-Kommando nutzen zu können, muss der DBA (oder auf Ihrer
Entwicklerdatenbank: Sie selbst) einige Vorbereitungen treffen. Auch wenn Sie mit einem
anderen Werkzeug arbeiten: Sie brauchen immer das Privileg für Abfragen im Data Dictionary; die
Rolle SELECT ANY DICTIONARY sollten Sie zur Diagnose langsamer SQL-Anweisungen also auf jeden Fall haben.
- Spielen Sie als SYS das Skript im Verzeichnis $ORACLE_HOME/sqlplus/admin/plustrce.sql
ein.
- Vergeben Sie die darin erzeugte Rolle PLUSTRACE an das Datenbankschema, mit dem Sie
arbeiten.
Verbinden Sie sich nun mit SQL*Plus auf Ihre Datenbank und setzen Sie das set autotrace-Kommando,
gefolgt von der SQL-Abfrage ab.
Neben dem Ausführungsplan (hier verkürzt dargestellt) sollten Sie dann etwa folgende Ausgabe sehen ...
Die Statistiken am Ende sind sehr interessant. Die consistent gets
besagen, wieviele Datenbankblöcke zur Ausführung der Abfrage gelesen werden
mussten (die physical reads geben an,
wieviele von der Platte geholt werden mussten). In der Beispieldatenbank ist
die Blockgröße der Datenbank 8Kb, für diese Abfrage wurden also ca. 252MB Daten gelesen.
Betrachtet man den Ausführungsplan, wird das ganze Dilemma dieser Abfrage schon deutlich:
Die SQL-Abfrage selektiert die Tabelle PRODUCTS und macht in der SELECT-Liste nochmals
vier Unterabfragen auf die (recht große) Tabelle SALES . Und jede dieser Abfragen wird
für sich ausgeführt, obwohl man, wenn man die Summe berechnet, auch direkt das Maximum,
das Minimum und den Durchschnitt ausrechnen kann. Was hier gemacht werden soll, ist eigentlich
ein Join - und das Umformulieren der Abfrage ...
... bringt einen besseren Ausführungsplan und massiv verbesserte Statistiken: Es werden
nur noch 1722 Datenbankblöcke (ca. 14MB) gelesen.
Und auch in der APEX-Anwendung profitiert man sofort von der verbesserten SQL-Abfrage. Wie
Abbildung 3 zeigt, werden im Beispiel anstelle von 2,38 Sekunden nur noch 1,25 Sekunden
benötigt.
Abbildung 3: APEX Anwendungsseite nach dem Tuning des Berichts
Tiefergehende Diagnose mit Tracing
Das Umschreiben der SQL-Abfrage hat also schon etwas geholfen. Bevor man nun über weitere
Tuning-Maßnahmen nachdenkt, wäre es hilfreich, noch etwas genauer zu wissen, was die Datenbank
in diesen 1,25 Sekunden genau getan hat. Und auch hierfür bietet APEX ein Werkzeug an. Fügen Sie
der URL der APEX-Anwendungsseite ein &p_trace=yes hinzu und rufen Sie sie erneut ab.
Zunächst sieht die Anwendungsseite genauso aus wie vorher. Im Hintergrund hat der Datenbankserver
nun allerdings eine sog. Tracedatei geschrieben. Sie liegt in der user dump destination; einem
speziellen Verzeichnis des Datenbankservers. Um an diese Datei heranzukommen, benötigen Sie
einen Betriebssystemzugriff für den Datenbankserver, also ggfs. die Hilfe des Datenbankadministrators.
Das folgende Listing zeigt eine Beispielkonfiguration. Wenn Sie mit dem PL/SQL Embedded Gateway
arbeiten, tragen die Tracedateien ein s00x im Namen, ansonsten beginnen Sie mit der SID der Datenbank,
gefolgt von "ora". Sie sollten sich den Zeitpunkt, zu dem Sie die URL mit dem Parameter P_TRACE
aufgerufen haben, gut behalten.
Diese Tracedateien sind allerdings nicht gut lesbar - daher werden sie im nächsten Schritt
mit dem Werkzeug tkprof lesbar gemacht. Am besten tun Sie das gleich auf dem Datenbankserver - sie sind
ja ohnehin gerade dort.
Die dabei entstandene Datei ausgabe.txt können Sie sich nun mit einem Texteditor ansehen. Sie finden
darin nun alle SQL-Anweisungen, die von APEX zum Aufbau der Webseite abgesetzt wurden, nebst detaillierten
Statistiken zu deren Ausführung. Enthalten sind übrigens auch APEX-Spezifische SQL-Abfragen und Anweisungen. Schaut man sich darin ein wenig um, so findet man auch die soeben
"getunte" SQL-Anweisung wieder ...
Die Tabelle direkt unterhalb der SQL-Anweisung gibt Informationen über die
verbrauchte Zeit und über die verarbeiteten Datenbankblöcke und Tabellenzeilen
wieder - letztere Information hatte auch schon das SQL*Plus Kommando set autotrace geliefert.
Interessant sind aber die Zeiten - diese werden ausgewiesen für die drei Phasen,
in denen eine SQL-Abfrage ausgeführt wird ...
- Parse: In dieser Phase wird zunächst die Syntax der SQL-Abfrage geprüft. Danach
wird festgestellt, ob benötigten Objekte und alle nötigen Privilegien vorhanden sind. Die Phase endet
mit der Erstellung des Ausführungsplans.
- Execute: In dieser Phase wird das SQL ausgeführt.
- Fetch: In dieser Phase wird die Ergebnismenge ausgelesen.
Im Beispiel verbrauchte die gesamte Abfrage ca. 2 Sekunden (etwas länger als oben) und
der größte Anteil davon war verbrauchte CPU-Zeit während der Fetch-Phase. Die Differenz (hier ca. eine Drittelsekunde)
sind Warte- und I/O-Zeiten. Da die SQL-Abfrage vor allem rechnet (Summe, Durchschnitt, Minimum und Maximum), ist
dieses Verhalten gut erklärbar.
Diese Information ist nun sehr wichtig für das weitere Tuning - denn eine solche
Maßnahme muss auf das Einsparen des CPU-Verbrauchs durch das Rechnen abzielen. Bei
der Art und Weise, wie das SQL ausgeführt wird (Join-Methode) oder bei den Plattenzugriffen
gibt es in diesem Beispiel nichts zu optimieren. Um es vorwegzunehmen: Die nächste Maßnahme
bei dieser Abfrage wäre eine Materialized View.
Diagnose aus der Entfernung: Oracle Enterprise Manager
Mitunter kommt es jedoch vor, dass sich Situationen am Entwickler-PC nicht so einfach nachstellen lassen;
denn die Berichtsausführung hängt vielfach von bestimmten Sitzungsparametern ab - und nicht zuletzt auch
von der konkreten Nutzer-ID. Administratoren und Entwickler bemerken solche Situationen meist nicht selbst;
sie werden vom Nutzer darauf hingewiesen: "Heute um 11:00 war die Applikation echt langsam" ... Mit dem
Oracle Enterprise Manager können allerdings auch solche Situationen nachträglich diagnostiziert werden. Da
Entwickler normalerweise nicht mit dem Enterprise Manager arbeiten, benötigen Sie hier wahrscheinlich die
Hilfe des Datenbankadministrators.
Die im Folgenden beschriebene Funktion des Oracle Enterprise Manager gehört zum Diagnostic Pack; um
das nachvollziehen zu können, muss neben der Enterprise Edition also das EM Diagnostic Pack lizensiert sein.
Die folgenden Screenshots sind mit dem Oracle EM Database Control gemacht - Database Control ist in der Installation
der Datenbanksoftware enthalten. Es wird davon ausgegangen, dass Database Control auf dem APEX-Datenbankserver
konfiguriert ist. Nach dem Einloggen in Database Control klicken Sie zunächst auf den Reiter Performance.
Abbildung 4: Oracle Enterprise Manager: Bereich "Performance"
Scrollen Sie ein wenig herunter und klicken Sie auf SQL Suchen (Abbildung 5).
Abbildung 5: SQL Suchen im Oracle Enterprise Manager
Klicken Sie oben links zunächst die Datenquellen an. Der Cursor Cache bezieht sich auf
die SQL-Informationen, die im Hauptspeicher des Datenbankservers liegen und bei Bedarf
wiederverwendet werden. Darüber hinaus schreibt die Datenbank diese Informationen in
regelmäßigen Abständen ins Automated Workload Repository (AWR); dort werden die Informationen
normalerweise 7 Tage lang aufgehoben.
Doch wie soll man in den vielen SQL-Anweisungen die richtige finden? Zum Glück
ist APEX hervorragend instrumentiert. Alles, was Sie wissen müssen, ist die
APEX Applikations-ID, die Seiten-ID und den APEX-Nutzernamen, mit dem gearbeitet wurde.
Stellen Sie den Filter entsprechend ein (Abbildung 6):
- Die Applikations-ID suchen Sie mit dem Filter MODUL; geben Sie ihn in der Form APEX:APPLICATION XXX ein.
- Die Seitennummer wird mit dem Filter AKTION gesucht; geben Sie ihn in der Form PAGE Y ein.
- Den APEX-Nutzernamen filtern Sie mit CLIENT_INFO.
Abbildung 6: APEX-Berichts-SQL im Enterprise Manager suchen
Nach Klick auf SQL Suchen wird Ihnen eine Liste passender SQL-Anweisungen aus der Cursor Cache bzw.
dem AWR präsentiert. Suchen Sie das passende SQL heraus und klicken Sie drauf. Sie sehen dann die
gleichen Details, die Sie mit dem SQL*Plus-Kommando set autotrace gesehen haben - nur dass Sie
hier direkt die Details der konkreten SQL-Ausführung des Nutzers sehen - es sind Originaldaten, keine
nachgestellten Tests. Den verwendeten Ausführungsplan können Sie sich im Bereich Plan oberhalb der Zusammenfassung ansehen.
Abbildung 7: Details eines konkret ausgeführten SQL-Kommandos
Zusammenfassung und Ausblick
APEX und die Oracle-Datenbank bieten verschiedene Varianten zur Analyse von SQL-Anweisungen
und Diagnose von Problemen an. Entwickler können gut mit SQL*Plus, dem #TIMING#-Schlüsselwort
oder dem Tracing arbeiten. Letzteres kann sogar für den Endanwender verfügbar gemacht werden;
so könnte man recht einfach einen Link auf der APEX-Seite platzieren, welcher die Seite
mit gleichen Parametern zuzüglich dem Parameter P_TRACE nochmal aufruft und vom Nutzer auf
Anweisung "des Supports" geklickt wird. Natürlich gibt es darüber hinaus zahlreiche, teils
kommerzielle, teils frei verfügbare Werkzeuge zur Diagnose von SQL-Problemen - alle aufzuzählen,
ist sicherlich unmöglich: Der Schwerpunkt des Tipps liegt auf den mit der Datenbank ohnehin
ausgelieferten Methoden.
Wie man diagnostizierte Probleme löst, also effizientes SQL- und PL/SQL schreibt, wird
in einem späteren Community-Tipp betrachtet.
Zurück zur Community-Seite
|