Daily CheckIn

This commit is contained in:
marcodn 2024-09-27 20:58:59 +02:00
parent ebec44cdee
commit 1f34a0a382
13 changed files with 161 additions and 168 deletions

View file

@ -22,6 +22,7 @@
"Planerstatistiken",
"Plantypen",
"SFSB",
"skriptbasierte",
"tabellenähnlichen",
"unterlagerte",
"unterlagerten",

View file

@ -14,7 +14,7 @@ Durch die nummerierten Präfixe können im Nachgang über die \textit{pgBadger}"
werden. Wichtig hierbei ist noch, dass vor dem \textit{measrun}-Aufruf überprüft wird, ob die Docker-Container
gestartet und initialisiert sind. Wenn dies nicht der Fall ist, laufen die Abfragen ins Leere. Am einfachsten ist das,
wie dargestellt, über die Statistik von Docker zu ermitteln. Darüber wird überwacht, das die CPU-Auslastung auf ein
niedriges Level fällt, danach kann das Skript für die Messungen gerufen werden.
niedriges Level fällt, danach kann das Skript für die Messungen aufgerufen werden.
\includecode[bash]{chapters/thesis/appendix04_calling_script.sh}{lst:calling_script}{Calling Script}

View file

@ -10,7 +10,7 @@
Für die Protokollierung der Abläufe im \ac{JSF} werden zwei Klassen benötigt. Über die Factory \ref{lst:logger_factory},
wird die Wrapper"=Klasse in die Bearbeitungsschicht eingeschleust. Diese Wrapper"=Klasse \ref{lst:logger} beinhaltet
dann die eigentliche Performance-Messung, inklusive der Ausgabe in die Log"=Datei des \textit{Glassfish}"=Servers.
dann die eigentliche Performance"=Messung, inklusive der Ausgabe in die Log"=Datei des \textit{Glassfish}"=Servers.
Zusätzlich muss in der Konfiguration \texttt{faces-config.xml} noch angepasst werden, wie in
\ref{lst:logger_factory_activate}, um die Factory durch das System aufrufen zu lassen.

View file

@ -3,12 +3,10 @@
\chapter{Einleitung}
\label{ch:intro}
\mytodos{Verena: Performance"=Verbesserung oder Perfromanceverbesserung?}
Die Akzeptanz und damit die Verwendung einer Software hängt von verschiedenen Kriterien
ab. Hierbei ist neben der Stabilität und der Fehlerfreiheit die Performance beziehungsweise
die Reaktionszeit der Software ein sehr wichtiges Kriterium. Hierfür muss sichergestellt
werden, dass die Anwendung immer in kurzer Zeit reagiert oder entsprechende Anzeigen dargestellt werden
werden, dass die Anwendung immer in kurzer Zeit reagiert oder entsprechende Anzeigen dargestellt werden,
um eine längere Bearbeitung anzuzeigen.
%\section{Motivation}
@ -53,48 +51,47 @@ eingesehen werden kann. Hierbei wurden sämtliche bislang bekannte Korrespondenz
Briefe selbst werden im etablierten TEI"=Format gespeichert und über einen WYSIWYG"=Editor von den Editoren und
Editorinnen eingegeben.
Das Projekt wurde anhand von bekannten und etablierten Entwurfsmustern umgesetzt um eine modulare und unabhängige
Das Projekt wurde anhand von bekannten und etablierten Entwurfsmustern umgesetzt, um eine modulare und unabhängige
Architektur zu gewährleisten, damit dies für weitere digitale Briefeditionen genutzt werden kann.
\section{Ziel der Arbeit}
\label{sec:intro:goal}
Die aktuelle Umsetzung beinhaltet die bisher definierten Anforderungen vollständig, darunter fallen die
Recherchemöglichkeiten, sowie auch die Eingabe und die Verarbeitung der Briefe. Ein größeres Problem hierbei ist die
Recherchemöglichkeiten sowie auch die Eingabe und die Verarbeitung der Briefe. Ein größeres Problem hierbei ist die
Performance der Oberfläche. Auf Grund der langen Abfragedauer des Datenbestandes leidet die Akzeptanz der Anwendung.
Das Ziel dieser Arbeit ist es, die Abfragedauer zu verringern, wodurch die Performance der Oberfläche signifikant
verbessert wird. \mytodos{verena}
verbessert wird.
\section{Gliederung}
\label{sec:intro:structure}
Zu Beginn der Arbeit werden im \autoref{ch:basics} die Struktur und der grundsätzliche Aufbau der Anwendung
Zu Beginn der Arbeit werden in \autoref{ch:basics} die Struktur und der grundsätzliche Aufbau der Anwendung
erklärt. Hierbei wird aufgezeigt an welchen Stellen es immer wieder zu Unstimmigkeiten kommen kann und wie diese zu
überprüfen sind.
Nachfolgend werden im \autoref{ch:concept} die Konzepte vorgestellt, die die Stellen ermitteln, die eine schlechte
Nachfolgend werden in \autoref{ch:concept} die Konzepte vorgestellt, die die Stellen ermitteln, welche eine schlechte
Performance aufweisen und optimiert werden sollen.
Hierzu gehören zum einen die Einstellungen der verwendeten Software, und zum anderen der Aufbau und die verwendeten
Techniken in der Anwendung. Diese Techniken werden im weiteren Verlauf nochmal überprüft, ob eine alternative Lösung
einen performantere Umsetzung bringen kann.
Bei den Performance"=Untersuchungen im \autoref{ch:performance-checking} werden nun die Konzepte angewandt, um
Bei den Performance"=Untersuchungen in \autoref{ch:performance-checking} werden nun die Konzepte angewandt, um
die Umgebung selbst zu untersuchen und die dort bekannten Probleme zu ermitteln. Diese werden direkt bewertet, unter den
Gesichtspunkten, ob eine Optimierung an dieser Stelle sinnvoll ist oder ob der Arbeitsaufwand dafür zu aufwendig ist.
Zusätzlich werden noch die Vorbereitungen und die angepassten Konfigurationen für die nachfolgenden
Performance"=Untersuchungen der Anwendung aufzeigt.
Zuerst wird im \autoref{ch:performance-investigation-application} die Ausgangsmessung durchgeführt, hierbei werden
Zuerst wird in \autoref{ch:performance-investigation-application} die Ausgangsmessung durchgeführt, hierbei werden
alle bekannten Caches deaktiviert und eine Messung durchgeführt.
Dann werden Schicht für Schicht die Optimierungsmöglichkeiten aufgezeigt, umgesetzt und erneut gemessen. Diese Messung
wird mit der Ausgangsmessung verglichen und bewertet.
Nach der Optimierung kommt nun die Evaluierung im \autoref{ch:evaluation}. Hier werden die verschiedenen Optimierungen
Nach der Optimierung kommt nun die Evaluierung in \autoref{ch:evaluation}. Hier werden die verschiedenen Optimierungen
begutachtet, in welchem Anwendungsfall die gewünschte Verbesserung in der Performance umgesetzt werden kann und welche
für den vorliegenden Fall in der Praxis umsetzbar ist.
\todo{verena}
Zum Abschluss im \autoref{ch:summary_and_outlook} \texthl{werden alle Optimierungen zusammengefasst und eine Abwägung}
Zum Abschluss in \autoref{ch:summary_and_outlook} werden alle Optimierungen zusammengefasst und eine Abwägung
getroffen, unter welchen Gesichtspunkten die Anpassungen eine sinnvolle Optimierung darstellen. Zusätzlich wird
beschrieben wie ein weiteres Vorgehen durchgeführt werden kann.

View file

@ -8,11 +8,10 @@ dass jeder Wechsel einer Seite oder eine Suchanfrage als Web"=Request an den Ser
geht durch mehrere Schichten des Server"=System bis die Antwort an den Client zurückgesendet wird, wie in
\autoref{fig:webrequest} dargestellt.
\todo{die rede sein????}
Es wird ab hier immer von einem \textit{Glassfish}"=Server die rede sein. In der Praxis wird ein \textit{Payara}"=Server
Es wird ab hier von einem \textit{Glassfish}"=Server die Rede sein. In der Praxis wird ein \textit{Payara}"=Server
verwendet. Der \textit{Glassfish}"=Server ist die Referenz"=Implementierung von Oracle, welche für Entwickler
bereitgestellt wird und die neuen Features unterstützt. Der \textit{Payara}"=Server ist aus dessen Quellcode entstanden
und ist für Produktivumgebungen gedacht, da dieser mit regelmäßigen Aktualisierungen versorgt wird. In dem weiteren Text
bereitgestellt wird und neue Features unterstützt. Der \textit{Payara}"=Server ist aus dessen Quellcode entstanden
und ist für Produktivumgebungen gedacht, da dieser mit regelmäßigen Aktualisierungen versorgt wird. Im folgenden Text
wird der Begriff \textit{Glassfish} verwendet.
Angefangen bei der Anfrage die über den Webbrowser an den Server gestellt wird und vom \textit{Glassfish}"=Server
@ -25,9 +24,9 @@ Hier wird nun geprüft, ob die Daten aus dem \textit{OpenJPA Cache} direkt ermit
an das unterlagerte Datenbankmanagementsystem \textit{PostgreSQL} weitergeleitet werden muss. Die ermittelten Daten vom
DBMS werden bei Bedarf im \textit{OpenJPA Cache} aktualisiert.
Das \textit{PostgreSQL} besteht aus mehreren Teilen die ineinander greifen um die Anfragen zu bearbeiten. Dabei
sind die \textit{Memory Buffers} notwendig um den Zugriff auf die Festplatte zu reduzieren um die Bearbeitungszeit
zu verringern. Um Anfragen die den Zugriff auf die Festplatte benötigen effizienter zu gestalten, bereiten die
Das \textit{PostgreSQL} besteht aus mehreren Teilen die ineinander greifen, um die Anfragen zu bearbeiten. Dabei
sind die \textit{Memory Buffers} notwendig, um den Zugriff auf die Festplatte zu reduzieren und die Bearbeitungszeit
zu verringern. Um Anfragen, die den Zugriff auf die Festplatte benötigen effizienter zu gestalten, bereiten die
\textit{Services} die Datenstrukturen auf.
\begin{figure}[!ht]
@ -75,7 +74,7 @@ zu verringern. Um Anfragen die den Zugriff auf die Festplatte benötigen effizie
In den Java"=EE"=Anwendungen wird der \textit{Persistenzkontext} für die Anfragen vom \textit{Application"=Server}
bereitgestellt. Hierfür werden \textit{Application"=Server} wie \textit{GlassFish} genutzt, um die Verwendung eines Pools
von Datenbankverbindungen zu definieren \citep[68]{MüllerWehr2012}. Dadurch kann die Anzahl der Verbindungen geringer
gehalten werden als die Anzahl der Benutzer die an der Anwendung arbeiten. Zusätzlich werden die Transaktionen über
gehalten werden als die Anzahl der Benutzer, die an der Anwendung arbeiten. Zusätzlich werden die Transaktionen über
\textit{\ac{SFSB}} gehandhabt, welche automatisch vor dem Aufruf erzeugt und danach wieder gelöscht
werden. Dies birgt allerdings den Nachteil, dass der \textit{Persistenzkontext} sehr groß werden kann, wenn viele
Entities in den \textit{Persistenzkontext} geladen werden. Da dies häufig zu Speicher"~ und damit Performance"=Problemen
@ -90,7 +89,7 @@ Objekte einen von vier Zuständen ein \citep[57]{MüllerWehr2012}. Im Zustand \t
aber noch nicht in den Cache überführt worden. Wenn diese in den Cache überführt worden sind, nehmen sie den Zustand
\texttt{Verwaltet} ein. Ist das Objekt aus dem Cache und der Datenbank entfernt worden, nimmt es den Zustand
\texttt{Gelöscht} an. \texttt{Losgelöst} ist der letzte Zustand, bei dem das Objekt aus dem Cache entfernt worden ist,
aber nicht aus der Datenbank.
aber noch in der Datenbank verbleibt.
Eine Menge von Objekten wird als \textit{Persistenzkontext} bezeichnet. Solange die Objekte dem
\textit{Persistenzkontext} zugeordnet sind, also den Zustand \texttt{Verwaltet} besitzen, werden diese auf Änderungen
@ -100,16 +99,15 @@ Eine Menge von Objekten wird als \textit{Persistenzkontext} bezeichnet. Solange
\section{Glassfish - OpenJPA Cache}
\label{sec:basics:ojpac}
\todo{... die Verwendung spricht... - das spricht umformen}
Zusätzlich kann im \textit{JPA} ebenfalls noch der \textit{Second Level Cache} (L2-Cache) aktiviert werden. Dieser steht
jedem \textit{Persistenzkontext} zur Verfügung und kann dadurch die Anzahl der Datenbankzugriffe deutlich reduzieren,
was bei langsamen Datenbank"=Anbindungen zu hohen Performance"=Gewinnen führen kann \citep[171]{MüllerWehr2012}.
\texthl{Zu Beachten ist, dass die Daten im \textit{Second Level Cache} explizit über die Änderungen informiert werden
müssen, weil sonst beim nächsten Aufruf veraltete Werte geliefert werden.} Ebenfalls benötigt ein Cache einen höheren Bedarf
Zu Beachten ist, dass die Daten im \textit{Second Level Cache} explizit über die Änderungen informiert werden
müssen, um zu verhindern, dass bei einem nachfolgenden Aufruf veraltete Werte zurückgegeben werden. Ebenfalls benötigt ein Cache einen höheren Bedarf
an Arbeitsspeicher, in dem die Daten parallel zur Datenbank bereitgestellt werden, daher ist die Benutzung nur
problemlos bei Entities möglich, auf welche meist lesend zugegriffen wird.
In der OpenJPA"=Erweiterung für den L2-Cache, wird in \textit{Objekt"=Cache} (in OpenJPA als \textit{DataCache}
In der OpenJPA"=Erweiterung für den L2-Cache wird in \textit{Objekt"=Cache} (in OpenJPA als \textit{DataCache}
bezeichnet) und \textit{Query"=Cache} unterschieden. Über die Funktionen \texttt{find()} und \texttt{refresh()} oder einer Query
werden die geladenen Entities in den Cache gebracht. Davon ausgenommen sind \textit{Large Result Sets} (Abfragen die
nicht alle Daten auf einmal laden), \texttt{Extent}"=Technologien und Queries, die einzelne Attribute von Entities
@ -131,11 +129,11 @@ die Einstellungen an den Entities angepasst werden \citep{IbmOpenJPACaching2023}
\label{sec:basics:memorybuffers}
Die Speicherverwaltung des PostgreSQL"=Servers muss für Produktivsysteme angepasst werden \citep[34-38]{Eisentraut2013}.
Hierunter fallen die \texttt{shared\_buffers} die bei circa 10 bis 25 Prozent des verfügbaren Arbeitsspeichers liegen
Hierunter fallen die \texttt{shared\_buffers}, die bei circa 10 bis 25 Prozent des verfügbaren Arbeitsspeichers liegen
sollten. Mit dieser Einstellung wird das häufige Schreiben des Buffers durch Änderungen von Daten und Indexen auf die
Festplatte reduziert.
Die Einstellung \texttt{temp\_buffers} definiert wie groß der Speicher für temporäre Tabellen pro
Die Einstellung \texttt{temp\_buffers} definiert, wie groß der Speicher für temporäre Tabellen pro
Verbindung maximal werden darf und sollte ebenfalls überprüft werden. Ein zu kleiner Wert bei großen temporären Tabellen
führt zu einem signifikanten Leistungseinbruch, wenn die Tabellen nicht im Hauptspeicher, sondern in einer Datei
ausgelagert werden.
@ -156,7 +154,7 @@ durchgeführt werden, damit die Performance des Systems durch die Änderungen de
\citep[75]{Eisentraut2013}. Hierfür gibt es den \texttt{VACUUM}"=Befehl, welcher entweder per Hand oder automatisch durch
das Datenbanksystem ausgeführt werden soll. Für die automatische Ausführung kann der maximal verwendete Speicher über
die Einstellung \texttt{autovacuum\_work\_mem} gesondert definiert werden \citep{PostgresPro:Chap20.4:2023}.
Neben dem Aufräumen durch \texttt{VACUUM}, sollten auch die Planerstatistiken mit \texttt{ANALYZE}
Neben dem Aufräumen durch \texttt{VACUUM} sollten auch die Planerstatistiken mit \texttt{ANALYZE}
\citep[83]{Eisentraut2013} aktuell gehalten werden, damit die Anfragen durch den Planer richtig optimiert werden können.
Für beide Wartungsaufgaben gibt es den Autovacuum"=Dienst, dieser sollte aktiv und richtig konfiguriert sein.
@ -167,16 +165,16 @@ ermittelt werden.
\section{PostgreSQL - Abfragen}
\label{sec:basics:queries}
Für weitere Optimierungen werden anschließend die Anfragen einzeln überprüft. Hierfür ist es sinnvoll die
Für weitere Optimierungen werden anschließend die Anfragen einzeln überprüft. Hierfür ist es sinnvoll, die
Ausführungspläne der Abfrage zu analysieren \citep[252]{Eisentraut2013}, die verschiedenen Plantypen und ihre Kosten zu
kennen, sowie die angegeben Werte für die Plankosten zu verstehen \citep[24-30]{Dombrovskaya2021}.
kennen sowie die angegeben Werte für die Plankosten zu verstehen \citep[24-30]{Dombrovskaya2021}.
Besonderes Augenmerk gilt dem Vergleichen des tatsächlich ausgeführten mit dem ursprünglichen Plan
\citep[254]{Eisentraut2013}. Eine der wichtigsten Kennzeichen hierbei ist, ob die Zeilenschätzung akkurat war.
Größere Abweichungen weißen häufig auf veraltete Statistiken hin.
\citep[254]{Eisentraut2013}. Eine \todo{eine oder eines?} der wichtigsten Kennzeichen hierbei ist, ob die Zeilenschätzung akkurat war.
Größere Abweichungen weisen häufig auf veraltete Statistiken hin.
Um die Abfragen selbst zu optimieren, gibt es ein Vorgehen über mehrere Schritte \citep[304-308]{Dombrovskaya2021}.
Zuerst wird unterschieden, ob es sich um eine \textit{Kurze} oder eine \textit{Lange} Abfrage handelt. Im Falle einer
\textit{Kurzen} Abfrage, werden zuerst die Abfragekriterien überprüft. Sollte dies zu keiner Verbesserung führen,
\textit{Kurzen} Abfrage werden zuerst die Abfragekriterien überprüft. Sollte dies zu keiner Verbesserung führen,
werden die Indexe geprüft. Ist dies ebenso erfolglos, wird die Abfrage nochmals genauer analysiert und so
umgestellt, dass die restriktivste Einschränkung zuerst zutrifft.
Bei einer \textit{Langen} Abfrage soll überprüft werden, ob es sinnvoll ist, das Ergebnis in einer Tabelle zu
@ -189,8 +187,8 @@ werden können, um die Abfragemenge zu verringern.
Bei \textit{Langen} Abfragen ist die Abhandlung >>Optimizing Iceberg Queries with Complex Joins<<
\citep{10.1145/3035918.3064053} ein zusätzlicher Ratgeber, um die Performance zu steigern.
Des Weiteren können über das Modul \texttt{pg\_stat\_statements} Statistiken der Aufrufe die an den Server gestellt
Des Weiteren können über das Modul \texttt{pg\_stat\_statements} Statistiken der Aufrufe, die an den Server gestellt
wurden, ermittelt werden \citep{PostgresF27:2023}. Hierbei können die am häufigsten Aufgerufenen und die Anfragen mit
der längsten Ausführungszeit ermittelt werden. Ohne zu dem zusätzlichen Modul, können die Statistiken über die
der längsten Ausführungszeit ermittelt werden. Ohne das zusätzliche Modul können die Statistiken über die
Software \textit{pgBadger} erstellt werden. Dafür muss zusätzlich noch die Konfiguration des \textit{PostgreSQL}
angepasst werden.

View file

@ -19,15 +19,15 @@ Hierunter fallen die Einstellungen für die \texttt{shared\_buffers}, der bei ei
circa 25\% des Arbeitsspeicher besitzen sollte \cite{PostgresC20.4:2024}.
Bei der Einstellung \texttt{temp\_buffers} geht es um den Zwischenspeicher für jede Verbindung, die bei der Verwendung
von temporären Tabellen verwendet wird. Dieser Wert sollte auf dem Standardwert von 8 MB belassen werden, lediglich bei
der Verwendung von großen temporären Tabellen verändert werden.
von temporären Tabellen verwendet wird. Dieser Wert sollte auf dem Standardwert von 8 MB belassen werden und lediglich
bei der Verwendung von großen temporären Tabellen verändert werden.
Der Speicher, der für eine Abfrage verwendet werden darf, wird über die Konfiguration \texttt{work\_mem} gesteuert.
Wenn der Speicher zu gering wird, werden die Zwischenergebnisse in temporäre Dateien ausgelagert. Der empfohlene Wert
berechnet sich aus \texttt{shared\_buffers} dividiert durch \texttt{max\_connections} \citep{ConfigTo12:online}.
Sollte die Berechnung außerhalb der Grenzwerte von 1 MB und 256 MB liegen, ist der jeweilige Grenzwert zu verwenden.
Um zu ermitteln, ob die Konfiguration richtig ist, muss im PostgreSQL die Einstellung \texttt{log\_temp\_files} auf 0
gesetzt werden. Mit dieser kann ermittelt, ob temporäre Dateien verwendet werden und deren Größe. Bei vielen kleineren
gesetzt werden. Mit dieser kann ermittelt, ob temporäre Dateien verwendet werden sowie deren Größe. Bei vielen kleineren
Dateien sollte der Grenzwert erhöht werden. Bei wenigen großen Dateien ist es ist sinnvoll den Wert so zu belassen.
Für die Wartungsaufgaben wie VACUUM oder dem Erstellen von Indexen wird die Begrenzung über die Einstellung
@ -38,14 +38,14 @@ Nachfolgend wird mit dem Systemtools, wie den Konsolenanwendungen \textit{htop}
überprüft. Hierbei ist die CPU"=Leistung, der aktuell genutzte Arbeitsspeicher, sowie die Zugriffe auf die Festplatte
die wichtigen Faktoren zur Bewertung.
Die CPU"=Leistung sollte im Schnitt 70\% nicht überschreiten, für kurze Spitzen wäre dies zulässig. Da sonst der
Server an seiner Leistungsgrenze arbeitet und dadurch es nicht mehr schafft die gestellten Anfragen schnell genug
abzuarbeiten.
Die CPU"=Leistung sollte im Schnitt 70\% nicht überschreiten, für kurze Spitzen wäre dies zulässig. Um zu verhindern, dass der
Server an seiner Leistungsgrenze arbeitet und es dadurch nicht mehr schafft, die gestellten Anfragen schnell genug
abzuarbeiten.\todo{Satz überarbeiten}
Da unter Linux der Arbeitsspeicher nicht mehr direkt freigegeben wird, ist hier die Page"=Datei der wichtigere Indikator.
Wenn dieses in Verwendung ist, dann benötigen die aktuell laufenden Programme mehr Arbeitsspeicher als vorhanden ist,
wodurch der aktuell nicht verwendete in die Page"=Datei ausgelagert wird. Hierdurch erhöhen sich die Zugriffszeiten auf
diese Elemente drastisch.
wodurch der aktuell nicht verwendete in die Page"=Datei ausgelagert wird. Zu beachten ist hierbei allerdings, dass sich
die Zugriffszeiten auf die Elemente drastisch erhöhen.
Die Zugriffsgeschwindigkeit, die Zugriffszeit sowie die Warteschlange an der Festplatte zeigt deren Belastungsgrenze auf.
In diesem Fall kann es mehrere Faktoren geben. Zum einem führt das Paging des Arbeitsspeicher zu erhöhten Zugriffen.
@ -55,7 +55,7 @@ zwischengespeichert werden kann und daher diese Daten immer wieder direkt von de
\section{Untersuchung der Anwendung}
\label{sec:concept:softwarestructure}
Bei der Performance"=Untersuchung der Anwendung, wird sich im ersten Schritt auf die Dokumentenliste beschränkt. Anhand
Bei der Performance"=Untersuchung der Anwendung wird sich im ersten Schritt auf die Dokumentenliste beschränkt. Anhand
dieser können die Optimierungen getestet und überprüft werden. Im Nachgang können die daraus gewonnenen Kenntnisse auf
die anderen Abfragen übertragen werden.
@ -72,7 +72,7 @@ Ort aufgehalten haben.
Da die Daten in der 3. Normalform in der Datenbank gespeichert werden, sind einige Relationen für die Abfragen
notwendig. Dies wird durch die generische Abfrage in \autoref{lst:documentlist} gezeigt. Zusätzlich wird für jedes
dargestellte Dokument eine zusätzliche Abfrage durchgeführt, die in \autoref{lst:documentlist_sub} zeigt, dass auch hier
dargestellte Dokument eine zusätzliche Abfrage durchgeführt, wie in \autoref{lst:documentlist_sub} zeigt, dass auch hier
weitere Relationen notwendig sind.
\includecode[SQL]{chapters/thesis/chapter03_documentlist.sql}{lst:documentlist}{Generische Abfrage der Dokumentenliste}
@ -82,13 +82,13 @@ Nach aktuellem Stand beinhaltet die Datenbank circa 5400 Briefe, für die jeweil
gespeichert werden. Diese Graphik-Dateien werden im TIFF-Format abgespeichert und benötigen zwischen 1 und 80 MB
Speicherplatz. Dadurch kommt die Datenbank aktuell auf circa 3,8 GB.
Wie im \autoref{ch:basics} dargestellt, besteht die eigentliche Anwendung aus mehreren Schichten. Die
PostgreSQL"=Schicht wurde schon im vorherigen Kapitel betrachtet. Daher gehen wir nun weiter nach oben in den Schichten
vom Glassfish"=Server.
Wie in \autoref{ch:basics} dargestellt, besteht die eigentliche Anwendung aus mehreren Schichten. Die
PostgreSQL"=Schicht wurde schon im vorherigen Kapitel betrachtet. Daher werden nun die weiteren Schichten des
Glassfish"=Server in aufsteigender Reihenfolge betrachtet.
Die OpenJPA Cache Schicht wird nun einzeln untersucht. Hierfür werden die zuerst die Cache"=Statistik für Object"=Cache
Die OpenJPA Cache Schicht wird nun einzeln untersucht. Hierfür werden zuerst die Cache"=Statistik für Object"=Cache
und Query"=Cache aktiviert \citep[315]{MüllerWehr2012}. Die somit erfassten Werte, werden über eine Webseite
bereitgestellt, um die Daten Live vom Server verfolgen zu können. Zusätzlich werden die Webseite über ein Script
bereitgestellt, um die Daten Live vom Server verfolgen zu können. Zusätzlich wird die Webseite über ein Script
aufgerufen und die Aufrufzeiten sowie andere externe Statistiken darüber erstellt und gespeichert.
In der \ac{JPA} Schicht sind die Anzahl der Entitäten im Persistence Context zu beobachten. Die Anzahl der verschiedenen
@ -112,27 +112,27 @@ Die Schicht \ac{EJB} besitzt keine Möglichkeit um eine sinnvolle Messung durchz
direkte Messungen eingefügt. Hier werden nur die externen Statistiken durch das Skript verwendet, um zu prüfen in
welchen Umfang die Umstellungen eine Veränderung im Verhalten der Webseite bewirken.
Bei den \ac{JSF} wird eine Zeitmessung eingefügt. Um sich in die Verarbeitung der Seiten einzuhängen, wird eine
\textit{Factory} benötigt. In dieser werden die Zeiten zum Ermitteln der Daten, das Zusammensetzen und das Rendern
Bei den \ac{JSF} wird eine Zeitmessung eingefügt. Um sich in die Verarbeitung der Seiten \todo{was ist an einzuhängen falsch?, das sich muss weg} einzuhängen, wird eine
\textit{Factory} benötigt. \todo{Umstellen weil 2x Ermitteln} In dieser werden die Zeiten zum Ermitteln der Daten, das Zusammensetzen und das Rendern
der Sicht ermittelt. Die Zeiten werden in die Log"=Datei des \textit{Glassfish}"=Servers hinterlegt und durch das
Skript ausgewertet. Somit ist es relativ leicht aufzuzeigen, an welcher Stelle der größte Teil der Verzögerung auftritt.
Skript ausgewertet. Somit ist es relativ leicht aufzuzeigen, an welcher Stelle die größte Verzögerung auftritt.
Die Abfragen werden ebenfalls untersucht und mit verschiedenen Methoden optimiert. Hierfür werden zum einen auf native
SQL"=Anfragen umgestellt und die Ausführungszeiten überprüft. Ebenfalls werden die Abfragen durch Criteria API erzeugt
SQL"=Anfragen umgestellt und die Ausführungszeiten überprüft. Zum anderen werden die Abfragen durch Criteria API erzeugt
und dessen Ausführungszeit ermittelt.
Zusätzlich werden im SQL-Server Optimierungen vorgenommen, darunter zählen die \textit{Materialized View}, welche eine
erweiterte Sicht ist. Neben der Abfrage der Daten beinhalteten diese auch noch vorberechneten Daten der Abfrage, womit
erweiterte Sicht ist. Neben der Abfrage der Daten beinhalteten diese auch vorberechneten Daten der Abfrage, womit
diese viel schneller abgefragt werden können. Zusätzlich werden die cached queries überprüft, ob diese eine Verbesserung
der Performance und der Abfragedauern verkürzen können.
Damit die Messungen nachvollziehbar bleiben, werden die Testaufrufe durch ein Bash-Script automatisiert gerufen.
Wichtig hierbei ist, dass die Webseite immer vollständig gerendert vom Server an den Client übertragen wird.
Somit kann die clientseitige Performance ignoriert werden, da alles Daten direkt in dem einen Aufruf bereitgestellt
wird. In dem Skript werden zum einen die Laufzeiten der Webanfragen ermittelt und die kürzeste, die längste und die
Somit kann die clientseitige Performance ignoriert werden, da alle Daten direkt in diesem Aufruf bereitgestellt
wird. In dem Skript werden zum einen die Laufzeiten der Webanfragen ermittelt,\todo{wie anders schreiben, zum einen - zum anderen} zum anderen die kürzeste, die längste und die
durchschnittliche Laufzeit ermittelt. Auf Grund der Speicherprobleme, werden auch die Speicherbenutzung des
\textit{Glassfish}"=Servers vor und nach den Aufrufen ermittelt. Zum Schluss werden noch die Log"=Dateien des
\textit{PostgreSQL}"=Servers über das Tool \textit{pgBadger} analysiert und als Bericht aufbereitet.
Um die Netzwerklatenz ignorieren zu können, wird das Skript auf dem gleichen Computer aufgerufen, auf dem der Webserver
gestartet wurde. Das zugehörige Script ist im \autoref{ap:timing} zu finden.
gestartet wurde. Das zugehörige Script ist in \autoref{ap:timing} zu finden.

View file

@ -50,7 +50,7 @@ ausgewertet werden.
Zusätzlich wird noch eine Implementierung der zugehörigen Factory"=Klasse \texttt{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 \texttt{faces-config.xml} eingetragen, wie das in
\autoref{lst:activate-factory} gezeigt wird, damit die Factory durch das System aufgerufen wird.
\autoref{lst:activate-factory} aufgezeigt wird, damit die Factory durch das System aufgerufen wird.
\begin{lstlisting}[language=xml,caption={Einbindung Factory},label=lst:activate-factory]
<factory>
@ -60,9 +60,9 @@ eingehängt. Diese Implementierung wird dann noch in der \texttt{faces-config.xm
</factor>
\end{lstlisting}
Der Quellcode der Klassen ist im \autoref{ap:jsf_performance_measure} zu finden.
Der Quellcode der Klassen ist in \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
Um die Abfragen im \textit{PostgreSQL} untersuchen zu können, ist es am einfachsten, 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.
@ -104,7 +104,7 @@ log_timezone = 'Europe/Berlin'
Das Untersuchen der protokollierten Abfragen auf Performance Optimierungen ist ein weiterer Bestandteil dieser Arbeit.
Das Schlüsselwort \texttt{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 welchem die Knoten die
darzustellen, um diese anschließend zu untersuchen. Der Abfrageplan ist als Baum dargestellt, bei welchem die Knoten die
unterschiedlichen Zugriffsarten darstellen. Die Verbindung der Knoten und der Aufbau zeigt die Operationen, wie
etwa 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
@ -122,25 +122,24 @@ EXPLAIN (ANALYZE, VERBOSE, BUFFERS, SUMMARY)
select * from document;
\end{lstlisting}
\todo{bei seq scan ... nochmal neu überlegen + Satz mit seigenden kosten fehlt}
Die zwei bekanntesten Knotentypen sind \texttt{Seq Scan} und \texttt{Index Scan}. \texthl{Wenn eine Tabelle Zeile für Zeile
gelesen wird,} zeigt der Abfrageplan einen \texttt{Seq Scan}"=Knoten an. Hierbei entsteht, unabhängig davon ob eine
Die zwei bekanntesten Knotentypen sind \texttt{Seq Scan} und \texttt{Index Scan}. Wenn eine Tabelle Zeile für Zeile
gelesen wird, zeigt der Abfrageplan einen \texttt{Seq Scan}"=Knoten an. Hierbei entsteht, unabhängig davon ob eine
Bedingung zum filtern vorhanden ist, eine unsortierte Liste dessen Startkosten entsprechend niedrig sind. Je weiter die
Liste durchlaufen wird, desto höher steigen die notwendigen Kosten. Die kostengünstigere Alternative ist der
\texttt{Index Scan}, bei dem der Index nach den Kriterien durchsucht wird, was meist durch den Aufbau des Index als
BTree (Multi"=Way Balanced Tree) rapide geht.
Eine weitere Optimierungsmöglichkeit ist die Verwendung von Indexe. Diese sind aber mit Bedacht zu wählen, da bei
Eine weitere Optimierungsmöglichkeit ist die Verwendung von Indexen. 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
ein Index bei jeder Änderung der Daten zusätzliche Arbeit, da dieser entsprechend mit gepflegt werden muss und ebenso
dessen Statistik muss regelmässig 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 aufwendigere Abfragen zu optimieren, bietet der PostgreSQL noch die Möglichkeit von
\textit{Materialized View}. Diese sind sehr ähnlich zu den Sichten, zusätzlich werden die Ergebnisse in einer
tabellenähnlichen Form abgespeichert. Somit sind die Zugriff auf diese Daten häufig performanter als die eigentliche Abfrage.
\textit{Materialized View}. Diese sind sehr ähnlich zu den Sichten, zusätzlich werden aber die Ergebnisse in einer
tabellenähnlichen Form abgespeichert, somit sind die Zugriff auf diese Daten häufig performanter als die eigentliche Abfrage.
Daher muss abgewägt werden, ob die Performance-Verbesserung trotz der zusätzliche Aktualisierung des Datenbestandes
als sinnvoll erachtet werden kann.

View file

@ -25,14 +25,14 @@ Hälfte des verfügbaren Arbeitsspeichers des Computers ungenutzt.
Mit der Konfiguration \texttt{-Xmx} wird der maximal verwendbare Heap"=Speicher in der \ac{JVM} definiert.
Dies zeigt direkt, dass es ein Problem in der Freigabe der Objekte gibt, da dass Erhöhen des verwendbaren
Arbeitsspeicher das Problem nicht löst, sondern nur verschiebt.
Arbeitsspeicher das Problem nicht löst, sondern nur verlagert.
Für alle nachfolgenden Messungen wird das Skript im \autoref{ap:calling_script} verwendet, welches die einzelnen
Aufrufe steuert. Die Ergebnisse werden in eine Tabelle überführt, wie in \autoref{tbl:measure-without-cache}.
Hierbei werden die Aufrufzeiten der Webseite aus dem Skript für die Zeitmessung mit Mindest"~, Durchschnitt"~ und
Maximalzeit aufgenommen, hierbei ist eine kürzere Zeit besser. Zusätzlich wird die Anzahl der aufgerufenen SQL Abfragen
ermittelt, auch hier gilt, dass weniger Aufrufe besser sind. Als letztes wird noch der verwendete Arbeitsspeicher
vom \textit{Glassfish}"=Server vor und nach dem Aufruf ermittelt und die Differenz gebildet, hierbei sollte im besten
ermittelt, auch hier gilt, je weniger Aufrufe desto besser. Als letztes wird noch der verwendete Arbeitsspeicher
vom \textit{Glassfish}"=Server vor und nach dem Aufruf ermittelt und die Differenz gebildet, hierbei sollte im idealen
Fall die Differenz bei 0 liegen. Dieser Aufbau gilt für alle weiteren Messungen. Zusätzlich werden noch die Laufzeiten
der \ac{JSF} ermittelt und die durchschnittlichen Zeiten mit in der Tabelle dargestellt, und auch hier ist es besser,
wenn die Zeiten kürzer sind.
@ -74,7 +74,7 @@ Da die Abfragezeiten auf der Datenbank zu gering waren, um eine Verbesserung fes
PostgreSQL und den Payara"=Server ein Docker"=Container erzeugt und diese limitiert. Die Konfiguration ist in
\autoref{ap:docker_config} beschrieben.
Mit dem neuen Aufbau ergeben sich nun eine neue Messung. Für den Speicherbedarf wird nun nicht mehr der benutzte
Mit dem neuen Aufbau ergibt sich eine neue Messung. Für den Speicherbedarf wird nun nicht mehr der benutzte
Speicher der Anwendung beobachtet, sondern die Speichernutzung des Docker-Containers für den Payara-Server. Auch hier
ist es besser, wenn es keine oder nur geringe Änderungen vor und nach dem Aufruf der Webseite gibt, ein steigender Wert
zeigt an, dass der verwendete Speicher nicht sauber freigegeben werden kann.
@ -84,9 +84,9 @@ Hierzu zählt die Hauptabfrage der Dokumenten"=-Tabelle, die Ermittlung des letz
die Ermittlung der Adressen des Autors, die Ermittlung der Koautoren, die Ermittlung der Faksimile, sowie die Ermittlung
der Anzahl aller vorhandenen Dokumente.
Zusätzlich wird die Zeit des Rendern der Sicht gemessen. Hierbei wird zum einen die komplette Zeit des Renderns
ermittelt. Innerhalb des Rendern wird dann noch die Zeit gemessen, wie lange es benötigt, die Daten aus der Datenbank
zu laden, und in die Java"=Objekte umzuformen.
Zusätzlich wird die Zeit des Rendern der Sicht gemessen. Die erste Messung erfasst die komplette Laufzeit die fürs Rendern
notwendig benötigt wird. Diese Zeit wird unterteilt in die Messungen für das Laden der Daten aus der Datenbank und das Erstellen
der Java"=Objekte inklusive dem Befüllen mit den geladenen Daten.
\begin{table}[h]
\centering
@ -115,7 +115,7 @@ zu laden, und in die Java"=Objekte umzuformen.
Die Cache"=Einstellung von OpenJPA werden über die zwei Einstellungen \texttt{openjpa.DataCache} und
\texttt{openjpa.QueryCache} konfiguriert. Bei beiden Einstellungen kann zuerst einmal über ein einfaches Flag
\textit{true} und \textit{false} entschieden werden ob der Cache aktiv ist. Zusätzlich kann über das Schlüsselwort
\textit{CacheSize} die Anzahl der Elemente im Cache gesteuert werden. Wird diese Anzahl erreicht, dann werden zufällige
\textit{CacheSize} die Anzahl der Elemente im Cache gesteuert werden. Wird diese Anzahl erreicht, werden zufällige
Objekte aus dem Cache entfernt und in eine SoftReferenceMap übertragen. Bei der Berechnung der Anzahl der Elemente werden
angeheftete Objekte nicht beachtet.
@ -206,7 +206,7 @@ die \textit{SoftReference} nicht das Problem für den steigenden Arbeitsspeicher
\label{tbl:measure-ojpa-active-bigger-no-softref}
\end{table}
Der Vergleich zeigt, dass der Cache eine gute Optimierung bringt, aber dies nur dann gut funktioniert, wenn immer
Der Vergleich zeigt, dass der Cache eine gute Optimierung bringt, aber dies kann nur dann gut funktionieren, wenn immer
wieder die gleichen Objekte ermittelt werden. Sobald die Anfragen im Wechsel gerufen werden oder einfach nur die Menge
der Objekte den Cache übersteigt, fällt die Verbesserung geringer aus.
@ -244,13 +244,14 @@ mit \ac{JPQL} oder Criteria API abfragt wird.
\section{Caching mit Ehcache}
\label{sec:performance-investigation-application:caching-ehcache}
\todo{hier weiter machen!!!!}
Der Ehcache ist ein L2"=Cache den man direkt in OpenJPA mit integrieren kann. Hierfür sind einige Punkte zu beachten.
Zum einen muss die Reference auf das \textit{ehcache} und das \textit{ehcache"=openjpa} Packet hinzugefügt werden.
Zum einen muss die Referenz auf das \textit{ehcache} und das \textit{ehcache"=openjpa} Paket hinzugefügt werden.
Zusätzlich dazu sind die Konfiguration \textit{openjpa.""QueryCache}, \textit{openjpa.""DataCache} und
\textit{openjpa.""DataCacheManager} auf \textit{ehcache} anzupassen. Anhand der Annotation \texttt{@DataCache} kann
an jeder Klasse die Benennung des Caches sowie die Verwendung selbst gesteuert werden. Es wird für jede Klasse ein
eigener Cache angelegt und der Name auf den vollen Klassennamen gesetzt. Die Verwendung ist für alle Klassen
aktiviert und müssen explizit deaktiviert werden, wenn dies nicht gewünscht ist. Als letztes muss noch der
aktiviert und muss explizit deaktiviert werden, wenn dies nicht gewünscht ist. Als letztes muss noch der
Cache"=Manager aktiviert werden, dieser kann entweder durch Code programmiert werden oder über eine Konfiguration
in der \textit{ehcache.xml}.
@ -258,7 +259,7 @@ Anhand der Auswertung von \ref{tbl:measure-ehcache-active} sieht man, dass der E
Verbesserung aufbringt. Über die Performance"=Statistik"=Webseite kann beobachtet werden, dass bei gleichen Aufrufen
der Webseite nur die Treffer in Cache steigen, aber die Misses nicht. Ebenfalls erhöht sich die Anzahl der Objekte
im Cache nicht. Zusätzlich steigt in diesem Fall der Speicherverbrauch nur gering bis gar nicht. Des Weiteren zeigt sich,
dass sich die Abfragezeiten in der Datenbank nur gering verkürzt wurden, aber die Laufzeit der Webseite sich stark
dass die Abfragezeiten in der Datenbank nur gering verkürzt wurden, aber die Laufzeit der Webseite sich stark
verbessert hat. Dies lässt auch hier den Schluss zu, dass die Erstellung der Objekte im OpenJPA die meiste Zeit
benötigt.
@ -289,13 +290,13 @@ benötigt.
\label{sec:performance-investigation-application:caching-ejb}
Die Cache"=Einstellungen des \ac{EJB} sind in der Admin-Oberfläche des Payara-Servers zu erreichen. Unter dem Punkt
Configurations $\Rightarrow$ server"=config $\Rightarrow$ EJB Container werden zum einem die minimalen und maximalen
Configurations $\Rightarrow$ server"=config $\Rightarrow$ EJB Container werden zum einen die minimalen und maximalen
Größen des Pools definiert werden. Zum anderen wird an dieser Stelle die maximale Größe des Caches und die Größe der
Erweiterung definiert.
Anhand der Auswertung der \autoref{tbl:measure-ejb-cache-active} ist ersichtlich, dass der \ac{EJB}"=Cache keine
Auswirkung auf die Performance hat. Ebenso ist es ersichtlich, dass die Anzahl der Datenbankabfragen nicht reduziert
wurden. Dies ist dadurch zu erklären, dass im \ac{EJB} die Provider gelagert werden, die über Dependency Injection
wurde. Dies ist dadurch zu erklären, dass im \ac{EJB} die Provider gelagert werden, die über Dependency Injection
den Controller bereitgestellt werden. Die Objekt selbst werden nicht im \ac{EJB}"=Cache hinterlegt.
% document, documentaddresseeperson, first/last, documentcoauthorperson, count und documentfacsimile
@ -362,11 +363,11 @@ Messung aus \autoref{tbl:measure-without-cache} entspricht.
Für die Optimierung wurden noch zusätzlich die Hints \texttt{openjpa.""hint.""OptimizeResultCount},
\texttt{javax.""persistence.""query.""fetchSize} und \texttt{openjpa.""FetchPlan.""FetchBatchSize} gesetzt. Hierbei
konnten je nach gesetzten Wert, keine relevanten Unterschiede festgestellt werden. Hierbei wurde der Wert auf zwei
gesetzt, welcher viel zu gering ist. Als weiterer Test wurde der Wert auf angefragte Größte gestellt und auf den
20"=fachen Wert der angefragten Größe.
gesetzt, welcher viel zu gering ist. Als weiterer Test wurde der Wert auf die angefragte Größe und den
20"=fachen Wert dieser Größe gestellt.
Ebenso bringt der Hint \texttt{openjpa.""FetchPlan.""ReadLockMode} auch keinen Unterschied bei der Geschwindigkeit.
Hierbei ist erklärbar, das im Standard bei einer reinen Selektion eine Lesesperre aktiv sein muss.
Dies ist dadurch erklärbar, dass im Standard bei einer reinen Selektion eine Lesesperre aktiv sein muss.
Bei \texttt{openjpa.""FetchPlan.""Isolation} wird gesteuert, auf welche Sperren beim Laden geachtet wird. Damit könnte
man lediglich Schreibsperren umgehen, und würde damit die Anfrage nicht mehr blockieren lassen, jedoch führt es unweigerlich
zu sogenannten >>Dirty"=Reads<<, wodurch die Ausgabe verfälscht werden könnte. Daher ist diese Einstellung
@ -378,10 +379,9 @@ Statement abgefragt. Mit \textit{join} wird definiert, dass abhängige Objekte d
definiert sind, in der Abfrage über einen Join verknüpft und damit direkt mitgeladen werden. Bei reinen
>>to-one<<"=Relation funktioniert das Rekursiv und spart sich damit einige einzelne Abfragen.
Bei der Einstellung \textit{parallel} wird zwar für jede abhängige Objektdefinition eine Abfrage ausgeführt und
\texthl{diese werden direkt auf die Hauptobjekte gefiltert und die Verknüpfung im} OpenJPA"=Framework durchgeführt.
\todo{das wurde umgebaut}
Somit muss in unserem Beispiel nicht für jedes Dokument eine einzelne Abfrage für die Koautoren durchgeführt werden,
sondern es wird nur eine Abfrage abgesetzt für alle Dokumente die ermittelt wurden. Technisch gesehen wird die gleiche
diese werden direkt auf die Hauptobjekte gefiltert und die Verknüpfung im OpenJPA"=Framework durchgeführt.
Somit muss in diesem Beispiel nicht für jedes Dokument eine einzelne Abfrage für die Koautoren durchgeführt werden,
es wird lediglich eine Abfrage für alle Dokumente welche ermittelt wurden abgesetzt. Technisch gesehen wird die gleiche
WHERE"=Abfrage nochmal durchgeführt und um die JOINS ergänzt, um die Daten der Unterobjekte zu ermitteln.
Mit dem Hint \texttt{openjpa.""FetchPlan.""SubclassFetchMode} ist die Konfiguration für Unterklassen definiert. Die
Möglichkeiten entsprechen der vom \texttt{openjpa.""FetchPlan.""EagerFetchMode}.
@ -428,8 +428,8 @@ if (myResultList != null && !myResultList.isEmpty()) {
\end{lstlisting}
Wie in der Messung in \autoref{tbl:measure-criteria-api} zu sehen, unterscheiden sich die Abfragezeiten nur marginal
von denen mit \ac{JPQL}. Wenn man sich den Code im Debugger betrachtet, \texthl{ist zu erkennen,} dass die zusammengesetzten
Abfragen in den Java-Objekten fast identisch sind. Und in der Datenbank sind die Anfragen identisch zu denen über JPQL.
von denen mit \ac{JPQL}. Wenn man sich den Code im Debugger betrachtet, lässt sich erkennen, dass die zusammengesetzten
Abfragen in den Java-Objekten fast identisch sind. In der Datenbank sind die Anfragen identisch zu denen über JPQL.
\begin{table}[h!]
\centering
@ -453,10 +453,10 @@ Abfragen in den Java-Objekten fast identisch sind. Und in der Datenbank sind die
\end{table}
Daher bringt die Criteria API keinen performance Vorteil gegenüber der JPQL"=Implementierung. Somit können beide
Implementierung ohne bedenken gegeneinander ausgetauscht werden, und die verwendet werden, die für den Anwendungsfall
Implementierungen ohne Bedenken gegeneinander ausgetauscht werden, und die verwendet werden, die für den Anwendungsfall
einfacher umzusetzen ist.
Bei den Hints ist es das gleiche wie bei \ac{JPQL}. Auch hier haben die meisten Hints keinen merkbaren Einfluss. Die
Bei den Hints ist es das Gleiche wie bei \ac{JPQL}. Auch hier haben die meisten Hints keinen merkbaren Einfluss. Die
Einstellung \texttt{openjpa.""FetchPlan.""EagerFetchMode} liefert auch hier Optimierungen, wenn der Wert auf
\textit{parallel} gestellt wird. Hier wird ebenfalls die Anzahl der Anfragen reduziert und damit auch die
Geschwindigkeit optimiert.
@ -612,14 +612,14 @@ vorhanden Elemente, welche die Liste der Dokumente anzeigt, kopiert und auf die
\label{tbl:measure-materialized-view}
\end{table}
Wie in \autoref{tbl:measure-materialized-view} zu sehen, bringt die Verwendung der \textit{Materialized View} eine
Verbesserung in verschiedenen Punkten. Zum einen ist eine Verbesserung der Aufrufzeiten zu erkennen, zusätzlich fällt
Wie in \autoref{tbl:measure-materialized-view} zu sehen ist, bringt die Verwendung der \textit{Materialized View} eine
Verbesserung in verschiedenen Punkten. Zum einen ist eine Verbesserung der Aufrufzeiten zu erkennen, zum anderen fällt
der Speicheranstieg weniger stark aus. Die Verbesserung der Aufrufzeiten lässt sich zusätzlich erklären, dass hier nun
nur noch vier statt der sechs an die Datenbank gestellt werden, da die Einzelabfragen für die Adressen der
Personen und der Koautoren komplett entfallen.
Nach dem der Quellcode nochmal untersucht wurde, konnte man festellen, dass bei jeder Anfrage die gleiche Bedingung
benötigt wurden. Da die Sicht nun explizit für dies Anfrage geschaffen wurde, wurde die Bedingungen nun direkt in die
Nach einer weiteren Untersuchung des Quellcodes konnte man festellen, dass bei jeder Anfrage die gleiche Bedingung
benötigt wurden. Da die Sicht nun explizit für diese Anfrage geschaffen wurde, wurde die Bedingungen nun direkt in die
Sicht mit integriert. Dies bedeutet eine Erweiterung der Sicht aus \autoref{lst:sql-materialized-view} um
\autoref{lst:sql-materialized-view-ext} und das Entfernen der Parameter aus dem SQL"=Anfragen im Java"=Code.
@ -654,22 +654,22 @@ zeigen nur minimale Unterschiede in den Zeiten, diese sind auf Messtoleranzen zu
Da bei der \textit{Materialized View} das Laden der Daten und das Wandeln in die Java"=Objekte getrennt programmiert
wurde, können hier eigene Zeitmessungen für die zwei Schritte eingebaut werden. Hierfür wird die Zeit vor dem
\texttt{map}"=Aufruf und der \texttt{map}"=Aufruf gemessen. Für den erste Messung, wurde vor der Datenbankabfrage ein
\texttt{SearchDocument} Objekt erzeugt und dieses in jedem \texttt{map}"=Aufruf zurückgegeben. Mit dieser Aufbau wurde
\texthl{die Zeit ermittelt, um die Daten aus der Datenbank zu laden und dieses Ergebnis einmalig zu durchlaufen} ohne ein \todo{verena}
\texttt{map}"=Aufruf und der \texttt{map}"=Aufruf gemessen. Für die erste Messung, wurde vor der Datenbankabfrage ein
\texttt{SearchDocument} Objekt erzeugt und dieses in jedem \texttt{map}"=Aufruf zurückgegeben. Mit diesem Aufbau wurde
die Zeit ermittelt, um die Daten aus der Datenbank zu laden und dieses Ergebnis einmalig zu durchlaufen ohne ein
Objekt zu erstellen. Hierbei lagen die Zeiten bei circa 1 ms für das reine Laden der Daten und 3 ms
für den Aufruf der \texttt{map}"=Funktion. Sobald innerhalb der \texttt{map}"=Funktion pro Eintrag ein Objekt
erzeugt wird, ohne die Konvertierung der ermittelten Daten in das Objekt, steigt die Laufzeit schon auf 54 ms.
erzeugt wird, ohne die Konvertierung der ermittelten Daten in das Objekt, steigt die Laufzeit bereits auf 54 ms.
Wenn man nun noch die Konvertierung der Daten mit einbaut, erhöht sich die Laufzeit nochmals, auf nun 82 ms.
Alleine für das Erzeugen der Objekte und der Json"=Parse Aufrufe wird die meiste Zeit aufgewendet.
Bei der Verwendung des Hints \texttt{openjpa.""FetchPlan.""FetchBatchSize} kann die Abfrage enorm verschlechtern. Wenn
Bei der Verwendung des Hints \texttt{openjpa.""FetchPlan.""FetchBatchSize} kann sich die Abfrage enorm verschlechtern. Wenn
dieser Wert zu klein oder groß definiert ist, wird die Laufzeit verschlechtert. Bei einem zu großen Wert wird die
Laufzeit der Datenbankanfrage auf circa 20 ms verlängert. Wenn der Wert zu gering gewählt ist, dann wird zwar die
Laufzeit der Datenbankanfrage minimal verkürzt, aber die \texttt{map}"=Funktion wird dadurch verlängert.
Das Aktivieren der Cache"=Optionen wie in \autoref{sec:performance-investigation-application:caching-openjpa} oder in
\autoref{sec:performance-investigation-application:cached-query} dargestellt, haben keine Auswirkung auf die Performance.
\autoref{sec:performance-investigation-application:cached-query} \todo{Umbruch} dargestellt, haben keine Auswirkung auf die Performance.
Dies ist dadurch erklärbar, das keine Objekte durch das OpenJPA"=Framework erstellt werden, sondern erst in der
\texttt{map}"=Funktion des eigenen Codes und daher wird der Cache nicht genutzt.
@ -697,7 +697,7 @@ die \textit{Json}"=Daten aufgerufen wird, wie beim laden der Webseite.
\end{lstlisting}
Die Interpreter"=Funktion, welche in JavaScript geschrieben ist, wird benötigt um die übertragenen
\textit{Json}"=Daten in eine darstelle Form zu bringen. Die Funktion aus dem \autoref{lst:jsf-datatable-json-convert}
\textit{Json}"=Daten in eine darstellbare Form zu bringen. Die Funktion aus dem \autoref{lst:jsf-datatable-json-convert}
ermittelt erst alle versteckten Elemente, deserialisiert den Inhalt und erstellt neue \textit{HTML}"=Elemente mit dem
darzustellenden Inhalt. Zusätzlich wird noch eine Zeitmessung eingebaut, um die Laufzeit am Client für das Rendern
in der Konsole anzuzeigen. Die Funktion wird nun direkt nach dem die Webseite fertig geladen wurde aufgerufen.
@ -746,7 +746,7 @@ $(document).ready(function() {
Da nun am Client der Code ausgeführt wird, nachdem die Daten übertragen wurden, kann nicht mehr alles über das Script
durchgeführt werden. Daher werden nun die Laufzeiten am Server und am Client zusammenaddiert. Im Schnitt benötigt der
Aufruf auf der Serverseite nun 70 ms und am Client sind es circa 13 ms. Die summierte Laufzeit von Client und Server
ist geringer als die reine Serverlösung und erzeugt gleichzeit weniger Last am Server. \mytodos{verena}
ist geringer als die reine Serverlösung und erzeugt gleichzeit weniger Last am Server.
\section{Optimierung der Abfrage}
\label{sec:performance-investigation-application:optimizing-query}

View file

@ -5,7 +5,7 @@
Nun werden die durchgeführten Anpassungen anhand ihre Effektivität betrachtet und unter welchen äußeren Einflüssen
diese eine Optimierung darstellen. Weiterhin werden die Nachteile der Anpassungen überprüft und und bei der Betrachtung
der Effektivität mit beachtet. \mytodos{verena}
der Effektivität mit beachtet.
Es wurden die Konfigurationen der Caches von OpenJPA, JPA und EJB aktiviert und deren Auswirkung betrachtet. Bei den
Caches, bei denen eine Größe angebbar ist, wurde zusätzlich mit der Anzahl variiert, um zu ermitteln in welchem Umfang
@ -25,8 +25,8 @@ wurde, ein rein technischer Ansatz.
\section{Umgestalten der Datenbanktabellen}
\label{sec:evaluation:new-table}
Hierfür wurde die aktuelle Datenstruktur untersucht um zu prüfen, ob eine Umgestaltung der Tabelle einen Verbesserung
bringen würden. Die typische Optimierung ist die Normalisierung der Tabellenstruktur. Die Tabellenstruktur ist aktuell
Hierfür wurde die aktuelle Datenstruktur untersucht um zu überprüfen, ob eine Umgestaltung der Tabelle einen Verbesserung
bringen würde. Die typische Optimierung ist die Normalisierung der Tabellenstruktur. Die Tabellenstruktur ist aktuell
schon normalisiert, daher kann hier nichts weiter optimiert werden.
Eine weitere Optimierungsstrategie besteht in der Denormalisierung, um sich die Verknüpfungen der Tabellen zu sparen.
@ -75,7 +75,7 @@ Optimierungsmöglichkeiten.
\section{Caching im OpenJPA}
\label{sec:evaluation:caching-jpa}
Bei der Verwendung des OpenJPA"=Caches gibt es einige Verbesserungen in der Geschwindigkeit zu sehen. Die Höhe der
Bei der Verwendung des OpenJPA"=Caches gibt es einige Verbesserungen bei der Geschwindigkeit zu sehen. Die Höhe der
Optimierungen hängt stark von der gewählten Cache"=Größe und der aufgerufenen Webseiten ab. Solange die Anfragen sich
auf die gleichen Objekte beziehen und diese alle im Cache hinterlegt werden können, fällt die Optimierung entsprechend
hoch aus. Sobald bei den Anfragen aber häufig die zu ermittelnden Objekte sich unterscheiden und alte Objekte wieder
@ -83,8 +83,8 @@ aus dem Cache entfernt werden, fällt die Performance"=Verbesserung immer gering
Das Entfernen der Objekte kann zwar umgangen werden, indem die häufig abgefragten Objekte gepinnt werden, was aber
den Speicherbedarf noch weiter erhöht, da diese Objekte nicht in die Zählung der Cache"=Objekte beachtet werden.
Was uns direkt zum größten Nachteil diese Caches kommen lässt, die notwendig Speichermenge die ständig zur Verfügung
gestellt werden muss. Damit ist immer ein gewisser Grundbedarf notwendig, da sich der Speicher bis zum eingestellten
Als größten Nachteil des Caches ist zu nennen, dass die notwendige Speichermenge ständig zur Verfügung gestellt
werden muss. Damit ist immer ein gewisser Grundbedarf notwendig, da sich der Speicher bis zum eingestellten
Grenzwert aufbaut und dann nicht mehr entleert wird. Gerade bei kleiner dimensionierten Servern stellt dies ein
größeres Problem dar, da nun weniger Speicher für die anderen laufenden Programme, wie dem Datenbankmanagementsystem,
zur Verfügung steht.
@ -106,7 +106,7 @@ explizit im Cache aufgenommen und angepinnt werden.
Die Optimierung über die gespeicherten Anfragen brachte keine Verbesserung hervor. Dies ist dadurch erklärbar, dass
für die diese Art nur Anfragen verwendet werden, die keinerlei Bedingungen besitzen. In diesem Fall sind in der Tabelle
noch nicht freigegebene und ungültige Datensätze gespeichert, daher müssen diese vor dem Übertragen herausgefiltert
werden. Aus diesem Grund werden die Anfragen in diesem Cache nicht gespeichert werden.
werden. Aus diesem Grund werden die Anfragen in diesem Cache nicht gespeichert.
Dadurch ist dieser Cache für eine Performance"=Verbesserung in dem Fall der Dokumentenliste nicht anwendbar.
@ -153,14 +153,14 @@ keine nennenswerten Einfluss auf die Laufzeit der Abfragen und Übertragung in d
von OptimizeResultCount, der FetchSize sowie der FetchBatchSize hilft dem Framework die Bearbeitung der Anfrage
effizient abzuarbeiten, konnte aber in den gemessenen Laufzeiten nicht verifiziert werden.
Anders verhält sich dies mit den Einstellungen für EagerFetchMode, welche definiert wie die Daten für abhängige Klasse
Anders verhält sich dies mit der Einstellung für \texttt{EagerFetchMode}, welche definiert, wie die Daten für abhängige Klassen
ermittelt werden. Bei der Umstellung auf \textit{parallel} konnte für die Ermittlung der Dokumente einiges an Performance gewonnen
werden. Das liegt daran, dass nun für die abhängigen Objekte, wie den Koautoren, nicht pro Dokument eine Anfrage an die
Datenbank gestellt wird, sondern es werden alle Koautoren für die ermittelten Dokumente auf einmal ermittelt. Die
Zuordnung der Koautoren zu dem Dokument wird dann nun im Framework und nicht mehr durch die Datenbank durchgeführt.
Diese Abarbeitung reduziert viele einzelne Abfragen und somit auch den entsprechend Overhead im Framework.
Auf Grund dessen ist die Entscheidung der Technik für die Performance irrelevant und es kann das genutzt werden, was für
Folglich ist die Entscheidung der Technik für die Performance irrelevant und es kann das genutzt werden, was für
jeweiligen Einsatzzweck besser beziehungsweise einfacher zu programmieren ist. Das Setzen der richtigen Hints wiederrum
ist in beiden Fällen äußerst wichtig. Explizit bei der EagerFetchMode muss vorher darüber nachgedacht werden, wie viele
abhängige Objekttypen es zu dieser Klasse gibt, welche dazu geladen werden sollen und von welcher Anzahl an Objekte
@ -172,11 +172,11 @@ Gleiches gilt dem Hint SubclassFetchMode, dieser steuert dimensionierte Abfragen
Die Idee der \textit{Materialized View} ist simple aber sehr effizient, gerade für einen Datenbestand welcher häufig gelesen
und selten verändert wird. Hierbei werden komplexe Abfragen einmalig ausgeführt und das Ergebnis intern
zwischengespeichert. Für alle weiteren Aufrufe, werden die Daten nun aus der Zwischenspeicher gelesen und dem Aufrufer
zwischengespeichert. Für alle weiteren Aufrufe, werden die Daten nun aus dem Zwischenspeicher gelesen und dem Aufrufer
zurückgegeben. Der größte Nachteil der \textit{Materialized View} ist, dass bei einer Änderung an den Quelldaten die
Sicht aktualisiert werden muss. Dieser Nachteil kommt in einer Briefedition nicht zum tragen, da in dieser nach dem die
Briefe einmalig eingepflegt wurden, nur noch selten Änderungen erfahren. Die Recherche über den Datenbestand die größte Zeit
gewidmet wird.
Briefe einmalig eingepflegt wurden, nur noch selten Änderungen erfahren. Die Recherche zu dem Datenbestand wird die
meiste Zeit gewidmet.
Ein weiterer Nachteil der \textit{Materialized View} ist die doppelte Speicherung der Daten, da die Daten für die Sicht
wie bei einer Tabelle auf der Festplatte gespeichert sind. Dieser Nachteil ist in der Dokumentliste vernachlässigbar,
@ -191,14 +191,14 @@ konnten schon viele zusätzliche Abfragen eingespart werden, da diese nicht mehr
für jede Datenzeile einzeln durchgeführt wird.
Zusätzlich konnte dies nochmal beschleunigt werden, in dem das Parsen der \textit{Json}"=Daten vom Server auf den Client
verlagert wurde. Hiermit konnte zum einen Last vom Server genommen werden und die gesamte Ausführungszeit nochmals
optimieren. Die Wandlung der Daten in \textit{HTML}"=Objekte ist eine Kernkompetenz von JavaScript und damit auch bei
verlagert wurde. Hiermit konnte ein Teil der Last vom Server genommen und die gesamte Ausführungszeit nochmals
optimiert werden. Die Wandlung der Daten in \textit{HTML}"=Objekte ist eine Kernkompetenz von JavaScript und damit auch bei
schwächeren Clients in kurzer Zeit durchführbar.
Als weiteren Punkt ist anzumerken, das der Speicherbedarf des Webserver relativ konstant bleibt ohne das ein Cache
verwendet wird. Der größte Unterschied zur Standardimplementierung ist die Verwendung von eigenen Code um die Objekte
Als weiteren Punkt ist anzumerken, dass der Speicherbedarf des Webserver relativ konstant bleibt ohne das ein Cache
verwendet wird. Der größte Unterschied zur Standardimplementierung ist die Verwendung von eigenen Codes um die Objekte
zu erstellen und zu befüllen und es nicht durch das OpenJPA"=Framework durchführen zu lassen.
Dies legt den Schluss nahe, dass es Probleme in der Speicherverwaltung der Objekte im OpenJPA"=Framework existieren.
Dies legt den Schluss nahe, dass Probleme in der Speicherverwaltung der Objekte im OpenJPA"=Framework existieren.
Zusammenfassend ist zu sagen, dass die \textit{Materialized View} eine gute Wahl ist, um die Listendarstellungen
zu optimieren. Mit dieser Technik können zum einen die Abfragezeiten optimiert werden, wodurch gleichzeit die
@ -209,7 +209,7 @@ ist oder direkt auf denormalisierte Daten umgestellt werden sollte, weil der zus
die Quelle ist.
Im Gegensatz zu einer reinen Cache"=Lösung die die gleiche Optimierung besitzt, ist diese vorzuziehen, da in den
meisten Fällen der Festplattenspeicher kostengünstiger als der Arbeitsspeicher ist. Zusätzlich ist der Cache begrenzt
und wirft alte Objekte aus dem Cache. Wenn dieser voll ist und wird ein Zugriff auf diese entfernten Objekte
und wirft alte Objekte heraus. Wenn dieser voll ist wird ein Zugriff auf diese entfernten Objekte
langsamer. Somit ist die Optimierung über die \textit{Materialized View} auf lange Zeit gesehen kostengünstiger und
stabiler.
@ -217,20 +217,21 @@ stabiler.
\label{sec:evaluation:optimize-query}
Die Abfragen die durch die OpenJPA an die Datenbank abgesetzt werden, sind meist durch ihre Einfachheit gut optimiert.
Nur durch Sortierung oder Bedingungen können die Abfragen langsam werden. Diese können durch entsprechende Indexe
Nur durch Sortierung oder Bedingungen können die Abfragen langsamer werden. Diese können durch entsprechende Indexe
gelöst werden. Bei größeren Abfragen mit mehreren Joins kann durch geschicktes umstellen die Performance verbessert
werden. Die Hauptabfrage der Dokumentenliste besteht aus mehreren Joins und diese wurde explizit untersucht.
Der Abfrageplan der Hauptabfrage wurde visuell untersucht und zeigt, dass das Hauptproblem die nicht eingeschränkte
Datenmenge der Haupttabelle \textit{document} ist. Dadurch werden zum einen die anderen Tabellen komplett dazu geladen
und es werden trotz direkter Primary Key Bedingungen keine Zugriffe über die Index durchgeführt. Für den PostgreSQL
Datenmenge der Haupttabelle \textit{document} ist. Dadurch werden die anderen Tabellen komplett geladen
anstatt die Zugriffe über die vorhandenen Indexe durchzuführen, obwohl die Bedingungen über die Primary Key definiert
sind. Für den PostgreSQL
ist es laut Berechnung kostengünstiger mit einem \textit{Seq Scan}, was einem kompletten Durchlaufen der Tabelle
entspricht, zu arbeiten.
Um dies zu optimieren, wurde über eine \textit{Common Table Expression} zuerst die eingeschränkten Datenzeilen
ermittelt, dieser mit der Haupttabelle verknüpft und nun die anderen Tabellen dazugenommen. Hierdurch konnten die
ermittelt, dieser mit der Haupttabelle verknüpft und nun die anderen Tabellen dazugenommen. Hierdurch konnte die
Zeilenanzahl während der Verarbeitung enorm verringert werden, wodurch einige der Verknüpfungen auf Indexzugriffe
umgestellt wurden. Durch die Umstellung konnte die Abfragezeit um mehr als das dreifache reduziert wurde.
umgestellt wurden. Durch die Umstellung konnte die Abfragezeit um mehr als das dreifache reduziert werden.
Mit dieser Art der Umstellung können Abfragen optimiert werden, die fürs Paging verwendet werden und die Abfrage aus
mehrere Tabellen besteht. Das Wichtigste hierbei ist, dass die Bedingungen und die Sortierkriterien auf der

View file

@ -12,19 +12,17 @@
Die Untersuchungen am Beispiel des Wedekind"=Projektes zeigen, dass mehrere Optimierungsmöglichkeiten in den
Briefeditionen existieren. Für die Untersuchung wurde sich auf die Dokumentenliste beschränkt und anhand dieser
die Optimierung implementiert, untersucht und jeweils mit der Ausgangsmessung vergleichen. Für die Messung wurden
Skripte erstellt, die auf dem gleichen Computer wie der Webserver und der Datenbankserver laufen, damit diese auch
Skripte erstellt, welche auf dem gleichen Computer wie der Webserver und der Datenbankserver laufen, damit diese auch
vergleichbar bleiben und externe Einflussfaktoren minimiert werden.
\mytodos{den Absatz hier drin lassen oder raus?}
%Messung zeigt wo die Probleme liegen! hier noch ausformulieren
Durch die Ausgangsmessungen war erkennbar, dass der größte Teil der Verarbeitungszeit im Bereitstellen der Entitäten
benötigt wird. Die Messung der Abfragen auf der Datenbank wiederum konnte die hohe Verarbeitungszeit nicht bestätigen,
daher lag hier schon die Vermutung nahe, dass der Großteil der Zeit im ORM"=Mapper verloren geht.
liegt. Die Messung der Abfragen auf der Datenbank wiederum konnte die hohe Verarbeitungszeit nicht bestätigen,
daher lag hier die Vermutung nahe, dass der Großteil der Zeit im ORM"=Mapper verloren geht.
Die Methode der Nutzerumfrage wurde nicht weiterverfolgt, da diese auf Grund zu wenigen Bedienern nicht zielführend war.
Bei der Untersuchung der Datenbank, wurde festgestellt, dass die Struktur aktuell für die Anwendung optimal ist und
Bei der Untersuchung der Datenbank wurde festgestellt, dass die Struktur aktuell für die Anwendung optimal ist und
daher eine Restrukturierung keine Vorteile entstehen lässt. Die statische Webseite und die komplett Client basierte
Webseite wurde auf Grund von technischen Einschränkungen nicht weiterverfolgt.
Webseite wurden auf Grund von technischen Einschränkungen nicht weiterverfolgt.
Bei den Caches sind der Query"=Cache und der EJB"=Cache nicht für die Optimierung verwendbar. Der Query"=Cache wird
von OpenJPA nur verwendet, wenn die Abfragen keine Parameter besitzt, welche in der Dokumentliste verwendet werden
@ -34,7 +32,7 @@ Performance festgestellt werden konnte.
Anders sieht es bei dem OpenJPA"=Cache aus, dieser hat direkten Einfluss auf die Performance der Ermittlung der Daten
und Bereitstellung der dazugehörigen Java"=Objekte. Anhand der vorgegeben Cache"=Größe kann das Potential der
Optimierung eingestellt werden. Dies bedeutet, soweit der Cache groß genug ist um alle notwendigen Objekte zu
speichern, sind die Verbesserung gut sichtbar. Ab dem Zeitpunkt ab dem Objekte aus dem Cache entfernt werden müssen,
speichern, sind die Verbesserungen gut sichtbar. Ab dem Zeitpunkt ab dem Objekte aus dem Cache entfernt werden müssen,
wird die Optimierung immer geringer.
Ein sehr ähnliches Verhalten konnte mit dem Ehcache festgestellt werden, nur dass bei diesem die Limitierungen höher
@ -44,41 +42,41 @@ In beiden Fällen der Optimierung über die Nutzung eines Caches, konnte durch d
Abfragen an der Datenbank nachgewiesen werden, dass nicht das Ermitteln der Daten die größte Zeit einnimmt, sondern
das Erstellen und Befüllen der Objekte in Java.
Bei dem Vergleich der unterschiedlichen Abfragemethoden Criteria API und JPQL konnte keine Unterschied in der
Bei dem Vergleich der unterschiedlichen Abfragemethoden Criteria API und JPQL konnte kein Unterschied in der
Performance und Abarbeitung festgestellt werden. Bei beiden Methoden konnte nachgewiesen werden, dass die syntaktisch
gleichen Abfragen an die Datenbank gestellt wurden. Bei den Abfragen zur Dokumentenliste konnten in beiden Fällen
durch die Umstellung der Ermittlung der unterlagerten Daten durch Hints eine Optimierung erreicht werden. Die Umstellung
bezweckt das die unterlagerten Daten nicht einzeln für jede Zeile ermittelt wurde, sondern alle Daten auf einmal
bezweckt das die unterlagerten Daten nicht einzeln für jede Zeile ermittelt wurden, sondern alle Daten auf einmal
geladen werden und die Zuordnung der Datensätze im OpenJPA"=Framework durchgeführt wird.
Mit der Übernahme der \textit{Materialized View} aus dem Wedekind"=Projekt konnte erstmalig ein gute Optimierung
beobachtet werden. Dies ist auf die einfachere Abfrage, die Reduzierung der Abfrage an den Datenbankserver und das
die Objekte in eigenen Code erstellt werden und nicht durch das OpenJPA"=Framework. Hierbei konnte noch nachgewiesen
die Objekte im eigenen Code erstellt werden und nicht durch das OpenJPA"=Framework. Hierbei konnte noch nachgewiesen
werden, dass das Parsen der Json"=Daten, die die unterlagerten Objekte enthalten, den größten Teil der Zeit benötigen.
Auf Grund dessen wurde das Parsen der Json"=Daten auf den Client verschoben, was zu einem noch besseren Ergebnis führte.
Für die Optimierung der Abfragen wurde die Hauptabfrage betrachtet. Bei dieser konnte anhand der visuellen Darstellung
das Problem gut identifiziert werden. Durch die Verwendung einer \textit{Common Table Expression} wurde die Anzahl
der Datensatze direkt am Anfang auf die angefragte Menge reduziert, wodurch die Anzahl der zu betrachteten Datensätze
für die weiteren Verlinkungen enorm reduziert wurden. Somit konnte der Datenbankserver bei diesen Verlinkung auf Indexe
der Datensätze direkt am Anfang auf die angefragte Menge reduziert, wodurch die Anzahl der zu betrachteten Datensätze
für die weiteren Verlinkungen enorm reduziert wurde. Somit konnte der Datenbankserver bei diesen Verlinkung auf Indexe
zugreifen und damit die Abfragen zusätzlich beschleunigen.
Die Untersuchungen zeigen, dass mehrere Möglichkeiten zur Optimierung existierten, um die Zugriffe auf die
Briefeditionen zu beschleunigen und das das größte Optimierungspotential in den ORM"=Mapper vorhanden ist. Welche der
Optimierungen verwendet werden, liegt zum einen an der Komplexität der Abfrage und der bereitgestellten Ressourcen
Briefeditionen zu beschleunigen und das das größte Optimierungspotential in dem ORM"=Mapper liegt. Welche der
Optimierungen verwendet werden, liegt an der Komplexität der Abfrage und der bereitgestellten Ressourcen
des Servers.
\section{Ausblick}
\label{sec:summary_and_outlook:outlook}
Die Untersuchungen zeigen, dass die Schichten über OpenJPA weitestgehend optimal umgesetzt sind, beziehungsweise wenig
Möglichkeiten für eine Optimierungen zu lassen. Einzig das Parsen von Json ist in einem Webbrowser schneller als im
Möglichkeiten für eine Optimierungen zulassen. Einzig das Parsen von Json ist in einem Webbrowser schneller als im
Server durchführbar. Auf diese Weise könnten zusätzlich die Ressourcen am Server reduziert werden beziehungsweise mit
gleichen Ressourcen mehr Anfragen als bisher beantwortet werden.
Die größten Optimierungspotentiale können durch Umstellung der Abfragen und der Optimierung des ORM"=Mappers umgesetzt
werden. Bei den Umstellungen der Abfragen ist größte Stärke, wenn die Anzahl der Abfragen drastisch reduziert werden
können.
könnte.
Dadurch zeigt sich, dass die Untersuchung auf Ebene der ORM"=Mapper noch nicht abgeschlossen ist. Weitere Untersuchungen
nach anderen ORM"=Mapper könnten wie in \ref{sec:evaluation:materialized-view} angedeutet das Speicherproblem lösen,

View file

@ -5,17 +5,17 @@
\pdfbookmark[0]{Zusammenfassung}{Zusammenfassung}
\chapter*{Zusammenfassung}
Die Briefedition des Wedekind"=Projektes stellt die Korrespondenz von Frank Wedekind als Online"=Volltextdatenbank
zur Verfügung um die Forschung an Frank Wedekind zu fokussieren. Um die Akzeptanz der Webseite zu erhöhen, damit
weitere Forscher sich mit dem Thema beschäftigen, soll die Reaktionszeit für die Anfragen reduziert werden.
zur Verfügung, um die Forschung an Frank Wedekind zu fokussieren. Um die Akzeptanz der Webseite zu erhöhen, damit
sich weitere Forscher mit dem Thema beschäftigen, soll die Reaktionszeit für die Anfragen reduziert werden.
Diese Arbeit betrachtet die verschiedenen Layer der Anwendung und die jeweiligen Optimierungsmöglichkeiten. Hierbei
wird ein rein technischer Ansatz gewählt, der durch Skript basierte Messungen überprüft und ausgewertet wird.
wird ein rein technischer Ansatz gewählt, der durch skriptbasierte Messungen überprüft und ausgewertet wird.
Betrachtet werden hierbei die Auswirkungen der verschiedenen Caches, die Abfragesprachen, eine Umstellung der
Abfragen auf \textit{Materialized Views} und die Optimierungsmöglichkeiten der Abfragen.
Es zeigt sich, dass die Ebenen unterschiedlich gute Optimierungsmöglichkeiten besitzen und die Caches die einfachste
Art der Optimierung sind, stattdessen benötigen diese zusätzliche Ressourcen im Sinne des Arbeitsspeichers.
Art der Optimierung ist, stattdessen benötigen diese zusätzliche Ressourcen im Sinne des Arbeitsspeichers.
Die Umstellung der \textit{Materialized View} inklusive der Zusammenfassung der unterlagerten Daten in eine Zeile
zeigt das größte Optimierungspotential. Durch die Umstellung der Abfragen kann ebenfalls die Verarbeitungszeit
reduziert werden, ist durch den größeren Anteil des ORM"=Mapper aber nicht stark ausschlaggebend.
reduziert werden, dies ist durch den größeren Anteil des ORM"=Mapper nicht stark ausschlaggebend.
\end{otherlanguage}

View file

@ -4,19 +4,18 @@
\begin{otherlanguage}{american}
\pdfbookmark[0]{Abstract}{Abstract}
\chapter*{Abstract}
\mytodos{Dies am Ende noch Ausfüllen!!!}
The Letter Edition of the Wedekind Project makes Frank Wedekind's correspondence available as an online
full"=text database in order to focus research on Frank Wedekind. In order to increase the acceptance of the
website so that more researchers can deal with the subject, the response time for inquiries is to be reduced.
A short summary of the contents in English of about one page. The following points should be addressed in particular:
\begin{itemize}
\item Motivation: Why did this work come about? Why is the topic of the work interesting (for the general public)? The motivation should be abstracted as far as possible from the specific tasks that may be given by a company.
\item Content: What is the content of this thesis? What exactly is covered in the thesis? The methodology and working method should be briefly discussed here.
\item Results: What are the results of this work? A brief overview of the most important results as a teaser to read the complete thesis.
\end{itemize}
\medskip
This paper looks at the different layers of the application and the respective optimization options. A purely
technical approach is chosen here, which is checked and evaluated using script-based measurements. The effects
of the different caches, the query languages, a conversion of the queries to materialized views and the
optimization possibilities of the queries are considered. views and the optimization possibilities of the queries.
\noindent
BTW: A great guide by Kent Beck how to write good abstracts can be found here:
\begin{center}
\url{https://plg.uwaterloo.ca/~migod/research/beckOOPSLA.html}
\end{center}
It can be seen that the levels have different optimization options and that the caches are the simplest type of
optimization, but instead require additional resources in terms of working memory. Converting the materialized
view, including combining the underlying data into one line, shows the greatest potential for optimization. The
processing time can also be reduced by converting the queries, but this is not very decisive due to the larger
proportion of the ORM mapper.
\end{otherlanguage}

Binary file not shown.