% !TeX root = ../../thesis.tex \chapter{Performance-Untersuchung} \label{ch:performance-checking} Für die Untersuchung der Performance"=Probleme sollten einige Vorbereitungen getroffen werden. Dazu gehören die Konfigurationen des Servers und in welcher Art und Umfang Anpassungen für die Performance"=Messung an der Software durchgeführt werden müssen. Hierbei ist zu beachten, dass die Anpassungen minimal sind, damit die Messung selbst nicht das Ergebnis verfälscht. Zum Abschluss wird noch auf die Untersuchung der Abfragen eingegangen, wie diese im PostgreSQL"=Server durchgeführt wird. \section{Überprüfung des Servers} \label{sec:performance-checking:server-checking} Die einfachste Art die Einstellungen am PostgreSQL"=Server zu überprüfen, ist die Abfrage von \ref{lst:postgresql-select-settings} am Datenbankserver auszuführen. \begin{lstlisting}[language=SQL,caption={Ermitteln der PostgreSQL Einstellungen},label=lst:postgresql-select-settings] SELECT name AS setting_name , setting AS setting_value , unit AS setting_unit FROM pg_settings WHERE name IN ( 'shared_buffers' , 'temp_buffers' , 'work_mem' , 'max_connections' , 'maintenance_work_mem' , 'autovacuum' ) \end{lstlisting} Zusätzlich sollte noch die aktuelle Auslastung des Server überprüft werden. Als Server wird hier ein Redhat"=Server mit der Standard"=Konfiguration des PostgreSQL"=Server 10 verwendet. Daher wird von einer richtigen Konfiguration der Speicher ausgegangen. Ebenfalls wird davon ausgegangen, dass der automatische Dienst für \textit{VACUUM} und \textit{ANALYZE} aktiv ist. Eine weitere Überprüfung des Servers ist nicht möglich, da kein Zugang zum aktuellen Produktionsservers möglich ist. \section{Einbau und Aktivieren von Performance-Messung} \label{sec:performance-checking:performance-measure} Um eine Messung der Performance in der Webseite durchführen zu können, gibt es in \ac{JSF} die Möglichkeit, über eine eigene Implementierung der Klasse \textbf{ViewDeclarationLanguageWrapper} sich in das generieren der Webseite einzuhängen. Hierbei können die Funktionen für das Erstellen, des Bauen und das Rendern der Webseite überschrieben werden. In den überschriebenen Funktionen werden nun Laufzeiten gemessen und die ermittelten Zeiten mit einer Kennung in die Log"=Datei eingetragen. Durch die Kennung, können die Zeiten im Nachgang über ein Script ermittelt und ausgewertet werden. Zusätzlich wird noch eine Implementierung der zugehörigen Factory"=Klasse \textbf{ViewDeclarationLanguageFactory} benötigt. Durch diese Factory"=Klasse wird der eigentlichen Wrapper mit der Performance-Messung in die Bearbeitungsschicht eingehängt. Diese Implementierung wird dann noch in der \textbf{faces-config.xml} eingetragen, wie das in \autoref{lst:activate-factory} gezeigt wird, damit die Factory durch das System aufgerufen wird. \begin{lstlisting}[language=xml,caption={Einbindung Factory},label=lst:activate-factory] de.wedekind.utils.VdlLoggerFactory \end{lstlisting} Der Quellcode der Klassen ist im \autoref{ap:jsf_performance_measure} zu finden. Um die Abfragen im \textit{PostgreSQL} untersuchen zu können, ist es am leichtesten, wenn man die Konfiguration so anpasst, dass alle Abfragen mit entsprechenden Zeitmessungen in die Log"=Datei ausgegeben werden. Über die Einstellungen in \autoref{lst:postgresql_logfile} wird die Datei und das Format der Ausgabe definiert. \begin{lstlisting}[language=yaml,caption={PostgreSQL Dateikonfiguration},label=lst:postgresql_logfile] log_destination = 'jsonlog' logging_collector = on log_directory = 'log' log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' log_file_mode = 0640 log_rotation_size = 100MB \end{lstlisting} Über die Konfiguration unter \autoref{lst:postgresql_logconf} wird definiert welche Werte protokolliert werden. Die wichtigste Einstellung ist \textit{log\_min\_duration\_statement}, diese definiert ab welcher Laufzeit eine Abfrage protokolliert werden soll. Mit dem Wert 0 werden alle Abfragen protokolliert. Alle weitere Einstellungen sind so gesetzt, dass nicht unnötige Abfragen für die spätere Auswertung mit \textit{pgBadger} protokolliert werden. Zusätzlich ist die Einstellung \textit{log\_temp\_files} auf 0 zu setzen. Dadurch werden alle erzeugten temporären Dateien und ihre Größe ebenfalls protokolliert. Diese Dateien entstehen, wenn der temporäre Puffer für die Abfrage nicht ausreicht und die Zwischenergebnisse ausgelagert werden müssen. \begin{lstlisting}[language=yaml,caption={PostgreSQL Ausgabekonfiguration},label=lst:postgresql_logconf] log_min_duration_statement = 0 log_autovacuum_min_duration = 10 log_checkpoints = off log_connections = on log_disconnections = on log_disconnections = on log_duration = off log_error_verbosity = default log_hostname = on log_lock_waits = on log_statement = 'none' log_temp_files = 0 log_timezone = 'Europe/Berlin' \end{lstlisting} \section{Prüfung von Abfragen} \label{sec:performance-checking:sql-query-checking} Das untersuchen der protokollierten Abfragen auf Performance Optimierungen ist ein weiterer Bestandteil dieser Arbeit. Das Schlüsselwort \textbf{EXPLAIN} ist im PostgreSQL vorhanden, um den Abfrageplan einer Abfrage zu ermitteln Und darzustellen, um diesen zu untersuchen. Der Abfrageplan ist als Baum dargestellt, bei dem die Knoten die unterschiedlichen Zugriffsarten darstellt. Die Verbindung der Knoten und der Aufbau zeigt die Operationen, wie etwas Joins, Aggregierung und Sortierung, und die Reihenfolgen der Abarbeitung. Zusätzlich sind auch Zwischenschritte, wie Zwischenspeicherungen ersichtlich. Zu jeder Operation gibt es neben dem Typ noch zusätzliche Informationen, wie die geschätzten Anlauf"= und Gesamtkosten (\textit{costs}), die geschätzte Anzahl der Zeilen (\textit{rows}) und die geschätzte Breite jeder Zeile (\textit{width}). Der Wert von \textit{costs} wird bei übergeordneten Knoten summiert. Bei der Option \textit{ANALYZE} wird die Abfrage ausgeführt und die echten Werte und Laufzeiten angezeigt. Ohne dieser, wird nur der Plan erstellt und dargestellt. Durch \textit{VERBOSE} werden zusätzliche Informationen zum Abfrageplan mit dargestellt und mit \textit{BUFFERS} werden die Informationen über die Nutzung der Caches mit dargestellt. Um an Ende noch eine Zusammenfassung mit anzuhängen, gibt es die Option \textit{summary}. Eine vereinfachte Form des Aufrufs ist in \autoref{lst:explain-easy} dargestellt. \begin{lstlisting}[language=SQL,caption={Aufruf von EXPLAIN},label=lst:explain-easy] EXPLAIN (ANALYZE, VERBOSE, BUFFERS, SUMMARY) select * from document; \end{lstlisting} \mytodos{hier noch die Typen der Knoten erklären?} Eine weitere Optimierungsmöglichkeiten sind die Verwendung von Indexe. Diese sind aber mit bedacht zu wählen, da bei mehreren Indexen die sehr ähnlich sind, nicht immer der gewünschte Index bei der Abfrage verwendet wird. Auch bedeutet ein Index bei jeder Änderung der Daten zusätzliche Arbeit, da dieser entsprechend mit gepflegt werden muss und auch dessen Statistik muss regelmässig mit aktualisiert werden. Ebenfalls ist die Reihenfolge der Spalte in einem zusammengesetzten Index von Bedeutung. Als Grundlage sollte hier mit der Spalte gestartet werden, welche die größte Einschränkung durchführt. Zusätzlich muss die Art des Index definiert werden, welche davon abhängig ist, mit welcher Vergleichsoperation auf die Tabellenspalte zugegriffen wird. Um größere und aufwendige Abfragen zu optimieren, bietet der PostgreSQL noch die Möglichkeiten von Materialisierten Sichten. Diese sind sehr ähnlich zu Sichten, speichern zusätzlich die Ergebnisse in einer tabellenähnlichen Form ab. Somit sind die Zugriff auf diese Daten häufig performanter als die eigentliche Abfrage. Die Performance wird durch die zusätzliche Aktualisierung des Datenbestand erkauft und muss daher abgewägt werden, was sinnvoller ist. \mytodos{das doch wieder raus? oder nur das mit create statistics drin lassen} Zusätzlich kann über die Systemtabelle \textit{pg\_statistic} oder die lesbarere Systemsicht \textit{pg\_stats} die aktuelle statistischen Informationen über eine Tabelle und deren Spalten ermittelt werden. In dieser Tabelle werden durch das \textit{ANALYZE} beziehungsweise \textit{VACUUM ANALYZE} Kommando die Informationen zum Anteil der \textit{NULL}"=Werte (null\_frac), Durchschnittlichen Größe (avg\_width), unterschiedlicher Werte (n\_distinct) und weitere gesammelt und für die Erstellung der Abfragepläne verwendet \citep{PostgreS39:online}. Diese Informationen können noch durch das Kommando \textit{CREATE STATISTICS} erweitert werden, für einen besseren Abfrageplan. Das aktivieren der zusätzlichen Statistiken sollten immer in Verbindung mit dem überprüfung des Abfrageplans durchgeführt werden, um zu ermitteln ob die Anpassung zu einer Optimierung und keiner Verschlechterung führt.