% !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]
<factory>
  <view-declaration-language-factory>
    de.wedekind.utils.VdlLoggerFactory
  </view-declaration-language-factory>
</factor>
\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.
