Daily CheckIn

This commit is contained in:
marcodn 2024-09-15 00:47:49 +02:00
parent e096c14dcc
commit 0d7fc1ae62
11 changed files with 272 additions and 161 deletions

55
.vscode/settings.json vendored
View file

@ -2,21 +2,27 @@
"cSpell.language": "de-de,en", "cSpell.language": "de-de,en",
"cSpell.words": [ "cSpell.words": [
"autovacuum", "autovacuum",
"Denormalisierung",
"editionswissenschaftlich", "editionswissenschaftlich",
"EFFW", "EFFW",
"Entitätsklassen",
"Fouine", "Fouine",
"freigeschalten", "freigeschalten",
"Galster", "Galster",
"Glassfish", "Glassfish",
"JPQL", "JPQL",
"Konsolenanwendungen", "Konsolenanwendungen",
"lesbarere",
"Multifunktionalität", "Multifunktionalität",
"parsen",
"Persistenzkontext", "Persistenzkontext",
"Planerstatistiken", "Planerstatistiken",
"Plantypen", "Plantypen",
"SFSB", "SFSB",
"tabellenähnlichen",
"unterlagerte", "unterlagerte",
"Wallstein", "vorverdichteten",
"Wallstein"
], ],
"cSpell.ignoreRegExpList": [], "cSpell.ignoreRegExpList": [],
"cSpell.overrides": [ "cSpell.overrides": [
@ -31,6 +37,7 @@
"Classname", "Classname",
"Datasource", "Datasource",
"Frontmatter", "Frontmatter",
"IntelliJ",
"JNDI", "JNDI",
"Laravel", "Laravel",
"Latexmk", "Latexmk",
@ -39,25 +46,71 @@
"Payara", "Payara",
"Poolname", "Poolname",
"Postgresql", "Postgresql",
"Redhat",
"Ressources", "Ressources",
"Servlet",
"Symfony", "Symfony",
"addresseeperson",
"adressee",
"ajax",
"american", "american",
"asadmin", "asadmin",
"authorperson",
"birthstartday",
"birthstartmonth",
"birthstartyear",
"classicthesis", "classicthesis",
"createdat",
"datetype",
"dcap",
"deathstartday",
"deathstartmonth",
"deathstartyear",
"documentaddresseeperson",
"documentcategory",
"documentcoauthorperson",
"documentfacsimile",
"documentid",
"downto", "downto",
"enddatestatus",
"endday",
"endmonth",
"endyear",
"ferniunithesis", "ferniunithesis",
"firstname",
"fmtutil", "fmtutil",
"gpasswd", "gpasswd",
"hcap",
"historicalperson",
"ispublishedindb",
"javax", "javax",
"jdbc", "jdbc",
"jsonlog",
"maxint", "maxint",
"modifiedat",
"ngerman", "ngerman",
"openjpa",
"pacman", "pacman",
"payara", "payara",
"payra", "payra",
"perfstat",
"personid",
"postgresql", "postgresql",
"println", "println",
"searchdocument",
"searchfulltext",
"searchreference",
"servlet",
"servlets",
"sitecity",
"startdate",
"startdatestatus",
"startday",
"startmonth",
"startyear",
"texlive", "texlive",
"typeof",
"validuntil",
"wedekind", "wedekind",
"xsep" "xsep"
], ],

View file

@ -9,12 +9,12 @@
\label{ap:calling_script} \label{ap:calling_script}
Um die Messungen etwas zu vereinfachen wurde ein Skript erstellt um die Aufrufe gesammelt durchzuführen. Um die Um die Messungen etwas zu vereinfachen wurde ein Skript erstellt um die Aufrufe gesammelt durchzuführen. Um die
Messungen durchzuführen werden die Befehl, wie in \ref{lst:calling_script_exec} dargestellt aufgerufen. Messungen durchzuführen werden die Befehl, wie in \autoref{lst:calling_script_exec} dargestellt aufgerufen.
Durch die nummerierten Präfixe können im Nachgang über die \textit{pgBadger}"=Berichte die \ac{SQL}"=Abfragen verglichen Durch die nummerierten Präfixe können im Nachgang über die \textit{pgBadger}"=Berichte die \ac{SQL}"=Abfragen verglichen
werden. Wichtig hierbei ist noch, dass vor dem \textit{measrun}-Aufruf überprüft wird, ob die Docker-Container 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, 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. Nun wird überwacht, das die CPU-Auslastung auf ein 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 Messung gerufen werden. niedriges Level fällt, danach kann das Skript für die Messungen gerufen werden.
\includecode[bash]{chapters/thesis/appendix04_calling_script.sh}{lst:calling_script}{Calling Script} \includecode[bash]{chapters/thesis/appendix04_calling_script.sh}{lst:calling_script}{Calling Script}

View file

@ -8,9 +8,10 @@
\chapter{JSF Performance Statistics Servlet} \chapter{JSF Performance Statistics Servlet}
\label{ap:jsf_performance_statistics_servlet} \label{ap:jsf_performance_statistics_servlet}
Um die Cache-Informationen über einen \ac{API}"=Aufruf bereitzustellen, wird ein Servlet \ref{lst:servlet} und ein Um die Cache-Informationen über einen \ac{API}"=Aufruf bereitzustellen, wird ein Servlet (\autoref{lst:servlet}) und ein
Provider \ref{lst:servlet_provider} benötigt. Für die Aufnahme in der Routing, wird noch ein zusätzlicher Eintrag in Provider (\autoref{lst:servlet_provider}) benötigt. Um das Servlet abfragen zu können, muss es in das Routing
der \textit{web.xml} benötigt \ref{lst:servlet_activate}. aufgenommen werden, hierfür wird noch ein zusätzlicher Eintrag in der \textit{web.xml} benötigt, der in
\autoref{lst:servlet_activate} dargestellt ist.
\includecode[java]{chapters/thesis/appendix05_servlet.java}{lst:servlet}{Performance Statistics Servlet} \includecode[java]{chapters/thesis/appendix05_servlet.java}{lst:servlet}{Performance Statistics Servlet}

View file

@ -29,9 +29,7 @@ sind die \textit{Memory Buffers} notwendig um den Zugriff auf die Festplatte zu
zu verringern. Um Anfragen die den Zugriff auf die Festplatte benötigen effizienter zu gestalten, bereiten die zu verringern. Um Anfragen die den Zugriff auf die Festplatte benötigen effizienter zu gestalten, bereiten die
\textit{Services} die Datenstrukturen auf. \textit{Services} die Datenstrukturen auf.
\mytodos{Grafik anders positionieren} \begin{figure}[!ht]
\begin{figure}[h]
\begin{tikzpicture}[node distance=5em, \begin{tikzpicture}[node distance=5em,
block/.style={rectangle, rounded corners,minimum width=3cm,minimum height=1cm,text centered, draw=black,fill=green!30}, block/.style={rectangle, rounded corners,minimum width=3cm,minimum height=1cm,text centered, draw=black,fill=green!30},
lineArrow/.style={arrows={-Latex[length=5pt 3 0]}}, lineArrow/.style={arrows={-Latex[length=5pt 3 0]}},

View file

@ -126,10 +126,10 @@ Die Abfragen werden ebenfalls untersucht und mit verschiedenen Methoden optimier
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. Ebenfalls werden die Abfragen durch Criteria API erzeugt
und dessen Ausführungszeit ermittelt. und dessen Ausführungszeit ermittelt.
Zusätzlich werden im SQL-Server Optimierungen vorgenommen, darunter zählen die materialized views, welche eine erweiterte Zusätzlich werden im SQL-Server Optimierungen vorgenommen, darunter zählen die Materialisierten Sichten, welche eine
View ist. Neben der Abfrage der Daten beinhalteten diese auch noch vorberechneten Daten der Abfrage, womit diese viel erweiterte Sicht ist. Neben der Abfrage der Daten beinhalteten diese auch noch vorberechneten Daten der Abfrage, womit
schneller abgefragt werden können. Zusätzlich werden die cached queries überprüft ob diese eine Verbesserung der diese viel schneller abgefragt werden können. Zusätzlich werden die cached queries überprüft ob diese eine Verbesserung
Performance und der Abfragedauern verkürzen können. der Performance und der Abfragedauern verkürzen können.
Damit die Messungen nachvollziehbar bleiben, werden die Testaufrufe durch ein Bash-Script automatisiert gerufen. Damit die Messungen nachvollziehbar bleiben, werden die Testaufrufe durch ein Bash-Script automatisiert gerufen.
Wichtig hierbei ist, das die Webseite immer vollständig gerendert vom Server an den Client übertragen wird. Wichtig hierbei ist, das die Webseite immer vollständig gerendert vom Server an den Client übertragen wird.

View file

@ -3,22 +3,17 @@
\chapter{Performance-Untersuchung} \chapter{Performance-Untersuchung}
\label{ch:performance-checking} \label{ch:performance-checking}
\section{Auswertung des Systems} Für die Untersuchung der Performance"=Probleme sollten einige Vorbereitungen getroffen werden. Dazu gehören die
\label{sec:performance-checking:system} 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.
\mytodos{Hier die Auswertung des Produktionsservers unterbringen} \section{Überprüfung des Servers}
\label{sec:performance-checking:server-checking}
\section{Statistiken im PostgreSQL auswerten} Die einfachste Art die Einstellungen am PostgreSQL"=Server zu überprüfen, ist die Abfrage von
\label{sec:performance-checking:postgresql-statistics} \ref{lst:postgresql-select-settings} am Datenbankserver auszuführen.
\mytodos{Logs auswerten, am besten vom Produktionsserver. Ebenfalls sollte man die Webseite
prüfen, die den Cache von OpenJPE auswerten}
\section{Überprüfung des PostgreSQL und Servers}
\label{sec:performance-checking:postgresql-checking}
Die einfachste Art die Einstellungen zu prüfen ist, die Abfrage in \ref{lst:postgresql-select-settings} am
Datenbankserver auszuführen.
\begin{lstlisting}[language=SQL,caption={Ermitteln der PostgreSQL Einstellungen},label=lst:postgresql-select-settings] \begin{lstlisting}[language=SQL,caption={Ermitteln der PostgreSQL Einstellungen},label=lst:postgresql-select-settings]
SELECT name AS setting_name SELECT name AS setting_name
@ -31,10 +26,16 @@ WHERE name IN (
, 'work_mem' , 'work_mem'
, 'max_connections' , 'max_connections'
, 'maintenance_work_mem' , 'maintenance_work_mem'
, 'autovacuum'
) )
\end{lstlisting} \end{lstlisting}
\mytodos{Konfiguration vom Produktionsserver prüfen} 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} \section{Einbau und Aktivieren von Performance-Messung}
\label{sec:performance-checking:performance-measure} \label{sec:performance-checking:performance-measure}
@ -49,7 +50,7 @@ ausgewertet werden.
Zusätzlich wird noch eine Implementierung der zugehörigen Factory"=Klasse \textbf{ViewDeclarationLanguageFactory} 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 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 eingehängt. Diese Implementierung wird dann noch in der \textbf{faces-config.xml} eingetragen, wie das in
\ref{lst:activate-factory} gezeigt wird, damit die Factory durch das System aufgerufen wird. \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] \begin{lstlisting}[language=xml,caption={Einbindung Factory},label=lst:activate-factory]
<factory> <factory>
@ -59,11 +60,11 @@ eingehängt. Diese Implementierung wird dann noch in der \textbf{faces-config.xm
</factor> </factor>
\end{lstlisting} \end{lstlisting}
Der Quellcode der Klassen ist im Anhang \ref{ap:jsf_performance_measure} zu finden. 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 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 des ausgegeben werden. anpasst, dass alle Abfragen mit entsprechenden Zeitmessungen in die Log"=Datei ausgegeben werden.
Zuerst werden über die Einstellungen unter \ref{lst:postgresql_logfile} die Datei und das Format definiert. Ü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] \begin{lstlisting}[language=yaml,caption={PostgreSQL Dateikonfiguration},label=lst:postgresql_logfile]
log_destination = 'jsonlog' log_destination = 'jsonlog'
@ -74,7 +75,7 @@ log_file_mode = 0640
log_rotation_size = 100MB log_rotation_size = 100MB
\end{lstlisting} \end{lstlisting}
Über die Konfiguration unter \ref{lst:postgresql_logconf} wird definiert welche Werte mit protokolliert werden. Die Ü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 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 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. gesetzt, dass nicht unnötige Abfragen für die spätere Auswertung mit \textit{pgBadger} protokolliert werden.
@ -97,3 +98,54 @@ log_statement = 'none'
log_temp_files = 0 log_temp_files = 0
log_timezone = 'Europe/Berlin' log_timezone = 'Europe/Berlin'
\end{lstlisting} \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.

View file

@ -24,12 +24,12 @@ in der Log-Datei protokolliert und der Server verwendet nun circa 4700 MB RSS. B
Hälfte des verfügbaren Arbeitsspeichers des Computers ungenutzt. 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. 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 Dies zeigt direkt, dass es ein Problem in der Freigabe der Objekte gibt, da dass erhöhen des verwendbaren
das Problem nicht löst, sondern nur verschiebt. Arbeitsspeicher das Problem nicht löst, sondern nur verschiebt.
Für alle nachfolgenden Messungen wird das Skript \ref{ap:calling_script} verwendet, welches die einzelnen Aufrufe Für alle nachfolgenden Messungen wird das Skript im \autoref{ap:calling_script} verwendet, welches die einzelnen
steuert. Die Ergebnisse werden in eine Tabelle überführt, wie in der Tabelle \ref{tbl:measure-without-cache}. Aufrufe steuert. Die Ergebnisse werden in eine Tabelle überführt, wie in der \autoref{tbl:measure-without-cache}.
Hierbei werden die Aufrufzeiten der Webseite aus dem Skript für die Zeitmessung mit Mindest"=, Durchschnitt"= und 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 Maximalzeit aufgenommen, hierbei ist eine kürzere Zeit besser. Zusätzlich wird die Anzahl der aufgerufenen SQL Abfragen
ermitteln, auch hier gilt, dass weniger Aufrufe besser sind. Als letztes wird noch der verwendete Arbeitsspeicher ermitteln, 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 vom \textit{Glassfish}"=Server vor und nach dem Aufruf ermittelt und die Differenz gebildet, hierbei sollte im besten
@ -38,20 +38,17 @@ der \ac{JSF} ermittelt und die durchschnittlichen Zeiten mit in der Tabelle darg
wenn die Zeiten kürzer sind. wenn die Zeiten kürzer sind.
Als Grundlage für die Vergleiche wurden eine Messung durchgeführt, bei der alle Caches deaktiviert wurden und keine Als Grundlage für die Vergleiche wurden eine Messung durchgeführt, bei der alle Caches deaktiviert wurden und keine
Änderung am Code vorgenommen wurde. Das Ergebnis dieser Messung ist in \ref{tbl:measure-without-cache} zu finden. Diese Änderung am Code vorgenommen wurde. Das Ergebnis dieser Messung ist in \autoref{tbl:measure-without-cache} zu finden.
zeigen auch direkt ein erwartetes Ergebnis, dass der erste Aufruf bedeutend länger dauert als die Nachfolgenden. Diese zeigen auch direkt ein erwartetes Ergebnis, dass der erste Aufruf bedeutend länger dauert als die Nachfolgenden.
Ebenfalls sieht man eindeutig, dass die Anzahl der Anfragen nach dem ersten Aufruf immer die gleiche Anzahl besitzen. Ebenfalls sieht man eindeutig, dass die Anzahl der Anfragen nach dem ersten Aufruf immer die gleiche Anzahl besitzen.
Der Speicherbedarf steigt auch relative gleichmässig, was nicht recht ins Bild passt, da hier keine Objekte im Cache Der Speicherbedarf steigt auch relative gleichmässig, was nicht recht ins Bild passt, da hier keine Objekte im Cache
gehalten werden sollten. gehalten werden sollten.
\mytodos{Diese Tabelle vielleicht auch einfach komplett streichen, da der Datenbestand anders ist, und das wichtigste \begin{table}[!h]
die Zeit der SQL-Abfragen nicht sichtbar ist}
\begin{table}[h!]
\centering \centering
\begin{tabular}{|r|r|r|r|r|r|r|r|} \begin{tabular}{|r|r|r|r|r|r|r|r|}
\hline \hline
& \multicolumn{3}{c}{Aufrufzeit (ms)} & & \multicolumn{3}{|c|}{RSS (MB)} \\ & \multicolumn{3}{c|}{Aufrufzeit (ms)} & & \multicolumn{3}{c|}{RSS (MB)} \\
\hline \hline
\# & min & avg & max & Queries & davor & danach & diff \\ \# & min & avg & max & Queries & davor & danach & diff \\
\hline \hline
@ -68,14 +65,14 @@ die Zeit der SQL-Abfragen nicht sichtbar ist}
Vor jedem weiteren Test-Lauf wurde die Domain beendet und komplett neugestartet, um mit einer frischen Instanz zu Vor jedem weiteren Test-Lauf wurde die Domain beendet und komplett neugestartet, um mit einer frischen Instanz zu
beginnen. Hierbei ist aufgefallen, dass fast immer 62 Abfragen zur Startup-Phase dazugehört haben, unabhängig von den beginnen. Hierbei ist aufgefallen, dass fast immer 62 Abfragen zur Startup-Phase dazugehört haben, unabhängig von den
konfigurierten Cache Einstellungen. Einige dieser Abfragen sind durch das Erstellen der Materialisierten Sichten konfigurierten Cache Einstellungen. Einige dieser Abfragen sind durch das Erstellen der Materialisierten Sichten
\textbf{searchreference} und \textit{searchfulltext} erklärbar. Zusätzlich ist noch ein zyklischer Dienst \textit{searchreference} und \textit{searchfulltext} erklärbar. Zusätzlich ist noch ein zyklischer Dienst
\textit{SearchEntityService} vorhanden, der zum Start und alle sechs Stunden den Datenbestand für die Suche aufbereitet \textit{SearchEntityService} vorhanden, der zum Start und alle sechs Stunden den Datenbestand für die Suche aufbereitet
und entsprechend einige Abfragen an die Datenbank absetzt. Da weder die Sichten noch der Dienst für die Dokumentenliste und entsprechend einige Abfragen an die Datenbank absetzt. Da weder die Sichten noch der Dienst für die Dokumentenliste
benötigt werden, wurde der Dienst und das Erstellen im Code für die weiteren Tests deaktiviert. benötigt werden, wurde der Dienst und das Erstellen im Code für die weiteren Tests deaktiviert.
Da die Abfragezeiten auf der Datenbank zu gering waren, um eine Verbesserung feststellen zu können, wurde für den Da die Abfragezeiten auf der Datenbank zu gering waren, um eine Verbesserung feststellen zu können, wurde für den
PostgreSQL und den Payara-Server ein Docker-Container erzeugt und diese limitiert. Die Konfiguration ist im Anhang PostgreSQL und den Payara-Server ein Docker-Container erzeugt und diese limitiert. Die Konfiguration ist im
\ref{ap:docker_config} beschrieben. \autoref{ap:docker_config} beschrieben.
Mit dem neuen Aufbau ergeben sich nun neue Messungen. Für den Speicherbedarf wird nun nicht mehr der benutzte Mit dem neuen Aufbau ergeben sich nun neue Messungen. 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 Speicher der Anwendung beobachtet, sondern die Speichernutzung des Docker-Containers für den Payara-Server. Auch hier
@ -121,9 +118,8 @@ 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. Eine weitere Optimierungsstrategie besteht in der Denormalisierung, um sich die Verknüpfungen der Tabellen zu sparen.
Dies ist in diesem Fall nicht anwendbar, da nicht nur 1:n Beziehungen vorhanden sind, sondern auch auch n:m Beziehungen. Dies ist in diesem Fall nicht anwendbar, da nicht nur 1:n Beziehungen vorhanden sind, sondern auch auch n:m Beziehungen.
Dadurch würden sich die Anzahl der Dokumentenliste erhöhen. Oder man muss die Duplikate auf der Serverseite Dadurch würden sich die Anzahl der Dokumentenliste erhöhen. Eine weitere Möglichkeit wäre es, die Duplikate auf der
zusammenführen. Serverseite zusammenzuführen.
\mytodos{Gefällt der Verena nicht so}
\section{Caching im OpenJPA} \section{Caching im OpenJPA}
\label{sec:performance-investigation-application:caching-openjpa} \label{sec:performance-investigation-application:caching-openjpa}
@ -137,16 +133,16 @@ angeheftete Objekte nicht beachtet.
Die Anzahl der Soft References kann ebenfalls über eine Einstellung gesteuert werden. Hierfür wird die Anzahl der Die Anzahl der Soft References kann ebenfalls über eine Einstellung gesteuert werden. Hierfür wird die Anzahl der
Elemente über \textit{SoftReferenceSize} gesetzt, dessen Wert im Standard auf \textit{unbegrenzt} steht. Mit dem Wert Elemente über \textit{SoftReferenceSize} gesetzt, dessen Wert im Standard auf \textit{unbegrenzt} steht. Mit dem Wert
\textit{0} werden die Soft Referencen komplett deaktiviert. Über die Attribute an den Entitätsklassen, können diese \textit{0} werden die Soft Referenzen komplett deaktiviert. Über die Attribute an den Entitätsklassen, können diese
Referenzen ebenfalls gesteuert werden, hierzu muss eine Überwachungszeit angegeben werden. Diese Zeit gibt in ms an, Referenzen ebenfalls gesteuert werden, hierzu muss eine Überwachungszeit angegeben werden. Diese Zeit gibt in ms an,
wie lange ein Objekt gültig bleibt. Mit dem Wert \textit{-1} wird das Objekt nie ungültig, was ebenfalls der wie lange ein Objekt gültig bleibt. Mit dem Wert \textit{-1} wird das Objekt nie ungültig, was ebenfalls der
Standardwert ist. Standardwert ist.
Zuerst wird mit aktivierten Cache mit einer Cache-Größe von 1000 Elemente getestet. Wie in \ref{tbl:measure-ojpa-active} Zuerst wird mit aktivierten Cache mit einer Cache-Größe von 1000 Elemente getestet. Wie in
zu sehen, dauert auch hier der erste Aufruf minimal länger als ohne aktiviertem Cache. Alle Nachfolgenden Aufrufe \autoref{tbl:measure-ojpa-active} zu sehen, dauert auch hier der erste Aufruf minimal länger als ohne aktiviertem
wiederrum sind um 100ms schneller in der Verarbeitung. Auch bei der Anzahl der Anfragen an die Datenbank kann der Cache. Alle Nachfolgenden Aufrufe wiederrum sind um 100ms schneller in der Verarbeitung. Auch bei der Anzahl der
Rückgang der Anfragen sehr gut gesehen werden. Aktuell kann die Verringerung des wachsenden Speicherbedarfs nur nicht Anfragen an die Datenbank kann der Rückgang der Anfragen sehr gut gesehen werden. Aktuell kann die Verringerung des
erklärt werden. wachsenden Speicherbedarfs nur nicht erklärt werden.
\begin{table}[h!] \begin{table}[h!]
\centering \centering
@ -170,12 +166,12 @@ erklärt werden.
\end{table} \end{table}
Bei einer erhöhten Cache-Größe, von 1000 auf 10000, zeigt sich auf den ersten Blick ein noch besseres Bild ab, wie in Bei einer erhöhten Cache-Größe, von 1000 auf 10000, zeigt sich auf den ersten Blick ein noch besseres Bild ab, wie in
\ref{tbl:measure-ojpa-active-bigger} ersichtlich ist. Der erste Aufruf entspricht der Laufzeit mit geringerer Cache-Größe, \autoref{tbl:measure-ojpa-active-bigger} ersichtlich ist. Der erste Aufruf entspricht der Laufzeit mit geringerer
aber schon die Anfragen an die Datenbank gehen drastisch zurück. Bei den weiteren Aufrufen werden im Schnitt nun nur Cache"=Größe, aber schon die Anfragen an die Datenbank gehen drastisch zurück. Bei den weiteren Aufrufen werden im
noch 6 Anfragen pro Seitenaufruf an die Datenbank gestellt, wodurch die Laufzeit im Schnitt nochmal um 100 ms Schnitt nun nur noch 6 Anfragen pro Seitenaufruf an die Datenbank gestellt, wodurch die Laufzeit im Schnitt nochmal
beschleunigt werden konnte. um 100 ms beschleunigt werden konnte.
\begin{table}[h!] \begin{table}[!ht]
\centering \centering
\resizebox{\textwidth}{!}{ \resizebox{\textwidth}{!}{
\begin{tabular}{|r|r|r|r|r|r|r|r|r|r|r|r|r|r|r|} \begin{tabular}{|r|r|r|r|r|r|r|r|r|r|r|r|r|r|r|}
@ -196,9 +192,9 @@ beschleunigt werden konnte.
\label{tbl:measure-ojpa-active-bigger} \label{tbl:measure-ojpa-active-bigger}
\end{table} \end{table}
Bei dem deaktivieren der \textit{SoftReference} und dem kleineren Cache zeigt sich keine große Differenz. Somit scheint Bei dem deaktivieren der \textit{SoftReference} und dem kleineren Cache zeigt sich keine große Differenz, somit scheint
die \textit{SoftReference} nicht das Problem für den steigenden Arbeitsspeicher zu sein, wie in Tabelle die \textit{SoftReference} nicht das Problem für den steigenden Arbeitsspeicher zu sein, wie in
\ref{tbl:measure-ojpa-active-bigger-no-softref} zu sehen. \autoref{tbl:measure-ojpa-active-bigger-no-softref} ersichtlich.
% document, documentaddresseeperson, first/last, documentcoauthorperson, count und documentfacsimile % document, documentaddresseeperson, first/last, documentcoauthorperson, count und documentfacsimile
\begin{table}[h!] \begin{table}[h!]
@ -229,11 +225,11 @@ der Objekte den Cache übersteigt, fällt die Verbesserung geringer aus.
\section{cached queries} \section{cached queries}
\label{sec:performance-investigation-application:cached-query} \label{sec:performance-investigation-application:cached-query}
Über die Einstellung \textit{openjpa.jdbc.QuerySQLCache} wird der Cache für abfragen aktiviert. Hierbei können Abfragen Über die Einstellung \textit{openjpa.""jdbc.""QuerySQLCache} wird der Cache für abfragen aktiviert. Hierbei können
angeben werden, die aus dem Cache ausgeschlossen werden. Der QueryCache wiederrum beachtet aber nur Abfragen die keine Abfragen angeben werden, die aus dem Cache ausgeschlossen werden. Der QueryCache wiederrum beachtet aber nur Abfragen
Parameter verwenden. Das sieht man auch entsprechend der Auswertung der Aufrufe \ref{tbl:measure-cached-queries}, die keine Parameter verwenden. Das sieht man auch entsprechend der Auswertung der Aufrufe in der
dass hier keine Veränderung der Aufrufzeiten stattgefunden hat. Gleich ob man mit \ac{JPQL} oder mit der Criteria API \autoref{tbl:measure-cached-queries}, dass hier keine Veränderung der Aufrufzeiten stattgefunden hat. Gleich ob man
abfragt. mit \ac{JPQL} oder mit der Criteria API abfragt.
% document, documentaddresseeperson, first/last, documentcoauthorperson, count und documentfacsimile % document, documentaddresseeperson, first/last, documentcoauthorperson, count und documentfacsimile
\begin{table}[h!] \begin{table}[h!]
@ -257,6 +253,8 @@ abfragt.
\label{tbl:measure-cached-queries} \label{tbl:measure-cached-queries}
\end{table} \end{table}
\mytodos{Queryzeiten fehlen nocht}
\section{Caching im JPA} \section{Caching im JPA}
\label{sec:performance-investigation-application:caching-jpa} \label{sec:performance-investigation-application:caching-jpa}
@ -305,6 +303,7 @@ abfragt.
\label{sec:performance-investigation-application:caching-ejb} \label{sec:performance-investigation-application:caching-ejb}
Die Cache-Einstellungen des \ac{EJB} sind in der Admin-Oberfläche des Payara-Servers zu erreichen. Hier Die Cache-Einstellungen des \ac{EJB} sind in der Admin-Oberfläche des Payara-Servers zu erreichen. Hier
\mytodos{Cache config noch definieren} \mytodos{Cache config noch definieren}
\begin{table}[h!] \begin{table}[h!]
@ -331,8 +330,8 @@ Die Cache-Einstellungen des \ac{EJB} sind in der Admin-Oberfläche des Payara-Se
\label{sec:performance-investigation-application:query-jpql} \label{sec:performance-investigation-application:query-jpql}
Für die \ac{JPQL} wird ein \ac{SQL} ähnlicher Syntax verwendet um die Abfragen an die Datenbank durchzuführen. Für die Für die \ac{JPQL} wird ein \ac{SQL} ähnlicher Syntax verwendet um die Abfragen an die Datenbank durchzuführen. Für die
Dokumentenliste wird der Code aus \ref{lst:jpql-document-list-jpql} verwendet. Die Namen mit vorangestellten Doppelpunkt Dokumentenliste wird der Code aus dem \autoref{lst:jpql-document-list-jpql} verwendet. Die Namen mit vorangestellten
sind Übergabevariablen. Doppelpunkt sind Übergabevariablen.
\begin{lstlisting}[language=Java,caption={JPQL Dokumentenliste},label=lst:jpql-document-list-jpql] \begin{lstlisting}[language=Java,caption={JPQL Dokumentenliste},label=lst:jpql-document-list-jpql]
SELECT DISTINCT d FROM Document d SELECT DISTINCT d FROM Document d
@ -344,9 +343,9 @@ AND d.isPublishedInDb = :published
ORDER BY d.documentId ASC ORDER BY d.documentId ASC
\end{lstlisting} \end{lstlisting}
In dem dazugehörigen Code am Server wird der JPQL-Code als NamedQuery hinterlegt und über den Name \textit{Document.findAll} In dem dazugehörigen Code am Server wird der JPQL-Code als NamedQuery hinterlegt und über den Name
referenziert. Eine Veränderung der Abfrage ist hier leider nicht möglich, wie man im Code \ref{lst:jpql-document-list} \textit{Document.""findAll} referenziert. Eine Veränderung der Abfrage ist hier leider nicht möglich, wie man im Code
sehen kann. aus \autoref{lst:jpql-document-list} sehen kann.
\begin{lstlisting}[language=Java,caption={Java JPQL Dokumentenliste},label=lst:jpql-document-list] \begin{lstlisting}[language=Java,caption={Java JPQL Dokumentenliste},label=lst:jpql-document-list]
List<Document> myResultList = createNamedTypedQuery("Document.findAll") List<Document> myResultList = createNamedTypedQuery("Document.findAll")
@ -364,41 +363,40 @@ if(myResultList != null && !myResultList.isEmpty()) {
\end{lstlisting} \end{lstlisting}
Da dieser Code direkt so aus dem Projekt kommt, wird hierfür keine gesonderte Zeitmessung durchgeführt, da diese der Da dieser Code direkt so aus dem Projekt kommt, wird hierfür keine gesonderte Zeitmessung durchgeführt, da diese der
Messung \ref{tbl:measure-without-cache} entspricht. Messung aus \autoref{tbl:measure-without-cache} entspricht.
Für die Optimierung wurden noch zusätzlich die Hints \textit{openjpa.hint.OptimizeResultCount}, Für die Optimierung wurden noch zusätzlich die Hints \textit{openjpa.""hint.""OptimizeResultCount},
\textit{javax.persistence.query.fetchSize} und \textit{openjpa.FetchPlan.FetchBatchSize} gesetzt. Hierbei konnten je \textit{javax.""persistence.""query.""fetchSize} und \textit{openjpa.""FetchPlan.""FetchBatchSize} gesetzt. Hierbei
nach gesetzten Wert, keine relevanten Unterschiede festgestellt werden. Hierbei wurde der Wert auf zwei gesetzt, konnten je nach gesetzten Wert, keine relevanten Unterschiede festgestellt werden. Hierbei wurde der Wert auf zwei
welcher viel zu gering ist. Als weiterer Test wurde der Wert auf angefragte Größte gestellt und auf den 20"=fachen gesetzt, welcher viel zu gering ist. Als weiterer Test wurde der Wert auf angefragte Größte gestellt und auf den
Wert der angefragten Größe. 20"=fachen Wert der angefragten Größe.
Ebenso bringt der Hint \textit{openjpa.FetchPlan.ReadLockMode} auch keinen Unterschied bei der Geschwindigkeit. Hierbei Ebenso bringt der Hint \textit{openjpa.""FetchPlan.""ReadLockMode} auch keinen Unterschied bei der Geschwindigkeit.
ist erklärbar, da im Standard bei einer reinen Selektion eine Lesesperre aktiv sein muss. Hierbei ist erklärbar, da im Standard bei einer reinen Selektion eine Lesesperre aktiv sein muss.
Bei \textit{openjpa.FetchPlan.Isolation} wird gesteuert, auf welche Sperren beim laden geachtet wird. Damit könnte man Bei \textit{openjpa.""FetchPlan.""Isolation} wird gesteuert, auf welche Sperren beim laden geachtet wird. Damit könnte
zwar schreibsperren umgehen, und würde damit die Anfrage nicht mehr blockieren lassen, aber es führt unweigerlich zu man zwar schreibsperren umgehen, und würde damit die Anfrage nicht mehr blockieren lassen, aber es führt unweigerlich
sogenannten \glqq Dirty"=Reads\grqq, wodurch die Ausgabe verfälscht werden könnte. Daher ist diese Einstellung sehr zu sogenannten \glqq Dirty"=Reads\grqq, wodurch die Ausgabe verfälscht werden könnte. Daher ist diese Einstellung sehr
mit Vorsicht zu verwenden. mit Vorsicht zu verwenden.
Mit dem Hint \textit{openjpa.FetchPlan.EagerFetchMode} wird definiert, wie zusammengehörige Objekte abgefragt werden. Mit dem Hint \textit{openjpa.""FetchPlan.""EagerFetchMode} wird definiert, wie zusammengehörige Objekte abgefragt werden.
Bei dem Wert \textit{none} werden nur die Basis"=Daten abgefragt und jedes weitere Objekt wird in einem eigenen Bei dem Wert \textit{none} werden nur die Basis"=Daten abgefragt und jedes weitere Objekt wird in einem eigenen
Statement abgefragt. Mit \textit{join} wird definiert, dass abhängige Objekte die als \glqq to-one\grqq"=Relation Statement abgefragt. Mit \textit{join} wird definiert, dass abhängige Objekte die als \glqq to-one\grqq"=Relation
definiert sind, in der Abfrage über einen Join verknüpft und damit direkt mitgeladen werden. Bei reinen definiert sind, in der Abfrage über einen Join verknüpft und damit direkt mitgeladen werden. Bei reinen
\glqq to-one\grqq"=Relation funktioniert das rekursive und spart sich damit einige einzelne Abfragen. \glqq to-one\grqq"=Relation funktioniert das rekursive und spart sich damit einige einzelne Abfragen.
Bei der Einstellung \textit{parallel} wird für zwar für jedes abhängigen Objektdefinition eine Abfrage durchgeführt, Bei der Einstellung \textit{parallel} wird für zwar für jedes abhängigen Objektdefinition eine Abfrage durchgeführt,
aber bei dieser wird der Einstieg über das Hauptobjekt durchgeführt. Somit muss in unserem Beispiel nicht für jedes aber bei dieser wird der Einstieg über das Hauptobjekt durchgeführt. Somit muss in unserem Beispiel nicht für jedes
Dokument eine einzelne abfrage für die CoAuthoren durchgeführt werden, sondern es wird nur eine Abfrage abgesetzt für 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 WHERE"=Abfrage nochmal durchgeführt und um alle Dokumente die ermittelt wurden. Technisch gesehen wird, die gleiche WHERE"=Abfrage nochmal durchgeführt und um
die JOINS ergänzt, um die Daten der Unterobjekte zu ermitteln. die JOINS ergänzt, um die Daten der Unterobjekte zu ermitteln.
Mit dem Hint \textit{openjpa.FetchPlan.SubclassFetchMode} ist die Konfiguraiton für Unterklassen definiert. Die Mit dem Hint \textit{openjpa.""FetchPlan.""SubclassFetchMode} ist die Konfiguration für Unterklassen definiert. Die
Möglichkeiten entsprechen der vom \textit{openjpa.FetchPlan.EagerFetchMode}. Möglichkeiten entsprechen der vom \textit{openjpa.""FetchPlan.""EagerFetchMode}.
Beim Umstellen der 2 Hints auf \textit{parallel} wird die Bearbeitungszeit fast halbiert und Anzahl der Datenbankaufrufe Beim Umstellen der 2 Hints auf \textit{parallel} wird die Bearbeitungszeit fast halbiert und Anzahl der Datenbankaufrufe
wurde fast geviertelt. Dies zeigt, dass die einzelnen Aufrufe je Dokument aufwendiger sind, als eine komplette Abfrage wurde fast geviertelt. Dies zeigt, dass die einzelnen Aufrufe je Dokument aufwendiger sind, als eine komplette Abfrage
der abhängigen Daten und das zusammensetzen in der OpenJPA-Schicht. der abhängigen Daten und das zusammensetzen in der OpenJPA-Schicht.
Der letzte Hint \textit{openjpa.FetchPlan.MaxFetchDepth} schränkt die rekursive Tiefe ein, für die abhängige Objekte Der letzte Hint \textit{openjpa.""FetchPlan.""MaxFetchDepth} schränkt die rekursive Tiefe ein, für die abhängige
mitgeladen werden. Damit wird zwar die Abfrage beschleunigt, aber nur aufgrund fehlender Datenbestände. Objekte mitgeladen werden. Lediglich auf Grund fehlender Datenbestände wird die Abfrage beschleunigt.
\mytodos{besser formulieren}
\section{Abfragen Criteria API} \section{Abfragen Criteria API}
\label{sec:performance-investigation-application:query-criteria-api} \label{sec:performance-investigation-application:query-criteria-api}
@ -406,7 +404,7 @@ mitgeladen werden. Damit wird zwar die Abfrage beschleunigt, aber nur aufgrund f
Für die Criteria API wird die Abfrage nicht in einem SQL-Dialekt beschreiben. Hierbei werden über Attribute die Für die Criteria API wird die Abfrage nicht in einem SQL-Dialekt beschreiben. Hierbei werden über Attribute die
Verlinkung zur Datenbank durchgeführt. An der Klasse selbst wird der Tabellenname definiert und an den Attributen die Verlinkung zur Datenbank durchgeführt. An der Klasse selbst wird der Tabellenname definiert und an den Attributen die
Spaltennamen. Um die Anfrage durchführen muss nun nur noch Datenklasse angegeben werden und mit den Parametern Spaltennamen. Um die Anfrage durchführen muss nun nur noch Datenklasse angegeben werden und mit den Parametern
versorgt werden, wie es in \ref{lst:criteria-api} gezeigt wird. versorgt werden, wie es in \autoref{lst:criteria-api} gezeigt wird.
\begin{lstlisting}[language=Java,caption={Criteria API Dokumentenliste},label=lst:criteria-api] \begin{lstlisting}[language=Java,caption={Criteria API Dokumentenliste},label=lst:criteria-api]
CriteriaBuilder cb = getEntityManager().getCriteriaBuilder(); CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
@ -434,9 +432,9 @@ if (myResultList != null && !myResultList.isEmpty()) {
} }
\end{lstlisting} \end{lstlisting}
Wie in der Messung \ref{tbl:measure-criteria-api} zu sehen, unterscheiden sich die Abfragezeiten nur marginal von Wie in der Messung in \autoref{tbl:measure-criteria-api} zu sehen, unterscheiden sich die Abfragezeiten nur marginal
denen mit \ac{JPQL}. Wenn man sich den Code im Debugger anschaut, sieht man auch, dass die zusammengesetzten Abfragen von denen mit \ac{JPQL}. Wenn man sich den Code im Debugger anschaut, sieht man auch, dass die zusammengesetzten
in den Java-Objekten fast identisch sind. Und in der Datenbank sind die Anfragen identisch zu denen über JPQL. Abfragen in den Java-Objekten fast identisch sind. Und in der Datenbank sind die Anfragen identisch zu denen über JPQL.
\begin{table}[h!] \begin{table}[h!]
\centering \centering
@ -463,11 +461,17 @@ Implementierung ohne bedenken gegeneinander ausgetauscht werden, und die verwend
einfacher umzusetzen ist. 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 \textit{openjpa.FetchPlan.EagerFetchMode} liefert auch hier Optimierungen, wenn der Wert auf Einstellung \textit{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 \textit{parallel} gestellt wird. Hier wird ebenfalls die Anzahl der Anfragen reduziert und damit auch die
Geschwindigkeit optimiert. Geschwindigkeit optimiert.
\section{materialized views} \section{Optimierung der Abfrage}
\label{sec:performance-investigation-application:optimizing-query}
Für die Optimierung der Abfrage wird zuerst die Hauptabfrage ermittelt, die auch in \autoref{lst:documentlist} zu
sehen ist.
\section{Materialized Views}
\label{sec:performance-investigation-application:materialized-views} \label{sec:performance-investigation-application:materialized-views}
Materialized Views sind Sichten in der Datenbank, die beim erstellen der Sicht den aktuellen Zustand ermitteln und Materialized Views sind Sichten in der Datenbank, die beim erstellen der Sicht den aktuellen Zustand ermitteln und
@ -477,16 +481,16 @@ Sichten auch Indexe erstellt werden, um noch effektiver die Abfragen bearbeiten
Der größte Nachteil dieser Sichten ist, dass sie zyklisch oder bei Datenänderungen aktualisiert werden müssen, sonst Der größte Nachteil dieser Sichten ist, dass sie zyklisch oder bei Datenänderungen aktualisiert werden müssen, sonst
läuft der Datenbestand der Sicht und der zugrundeliegenden Abfrage auseinander. Da die Hauptarbeiten auf der Webseite läuft der Datenbestand der Sicht und der zugrundeliegenden Abfrage auseinander. Da die Hauptarbeiten auf der Webseite
die Abfrage der Daten ist, und nicht das editieren, kann dieser Nachteil bei entsprechender Optimierung igoriert ewrden. die Abfrage der Daten ist, und nicht das editieren, kann dieser Nachteil bei entsprechender Optimierung ignoriert werden.
In diesem Test, wurde zusätzlich zur normalen Abfragen noch die nachfolgenden einzelabfragen als Sub-Selects In diesem Test, wurde zusätzlich zur normalen Abfragen noch die nachfolgenden einzelabfragen als Sub-Selects
hinzugefügt, wie in \ref{lst:sql-materialized-view} zu sehen. Somit können die nachfolgenden einzelnen Abfragen hinzugefügt, wie in \autoref{lst:sql-materialized-view} zu sehen. Somit können die nachfolgenden einzelnen Abfragen
eingespart werden. Dies wiederrum geht aber auf die Performance der Erstellung der Sicht und ihrer Aktualisierung. eingespart werden. Dies wiederrum geht aber auf die Performance der Erstellung der Sicht und ihrer Aktualisierung.
\begin{lstlisting}[language=SQL,caption={SQL Materialized View},label=lst:sql-materialized-view] \begin{lstlisting}[language=SQL,caption={SQL Materialized View},label=lst:sql-materialized-view]
CREATE MATERIALIZED VIEW searchdocument AS CREATE MATERIALIZED VIEW searchdocument AS
SELECT SELECT
d.id, d.documentId, d.datetype, d.startdatestatus, d.startyear, d.id, d.documentid, d.datetype, d.startdatestatus, d.startyear,
d.startmonth, d.startday, d.enddatestatus, d.endyear, d.endmonth, d.startmonth, d.startday, d.enddatestatus, d.endyear, d.endmonth,
d.endday, d.endday,
( (
@ -565,7 +569,7 @@ LEFT JOIN sitecity sc ON sc.id = d.city_id;
\end{lstlisting} \end{lstlisting}
Zusätzlich werden noch einige Indexe hinzugefügt, für eine bessere Performance bei der Abfrage, wie in Zusätzlich werden noch einige Indexe hinzugefügt, für eine bessere Performance bei der Abfrage, wie in
\ref{lst:sql-materialized-view-index} zu sehen. \autoref{lst:sql-materialized-view-index} zu sehen.
\begin{lstlisting}[language=SQL,caption={SQL Materialized View},label=lst:sql-materialized-view-index] \begin{lstlisting}[language=SQL,caption={SQL Materialized View},label=lst:sql-materialized-view-index]
CREATE INDEX idx_searchdocument_documentid CREATE INDEX idx_searchdocument_documentid
@ -612,7 +616,7 @@ CREATE INDEX idx_searchdocument_documentcategory
\label{tbl:measure-materialized-view} \label{tbl:measure-materialized-view}
\end{table} \end{table}
Wie in Tabelle \ref{tbl:measure-materialized-view} zu sehen, bringt die Verwendung der Materialized View ein Verbesserung Wie in \autoref{tbl:measure-materialized-view} zu sehen, bringt die Verwendung der Materialized View ein Verbesserung
in verschiedenen Punkten. Zum einen ist eine Verbesserung der Aufrufzeiten zu erkennen, zusätzlich fällt der in verschiedenen Punkten. Zum einen ist eine Verbesserung der Aufrufzeiten zu erkennen, zusätzlich fällt der
Speicheranstieg weniger stark aus. Die Verbesserung der Aufrufzeiten lässt sich zusätzlich erklären, dass hier nun Speicheranstieg weniger stark aus. Die Verbesserung der Aufrufzeiten lässt sich zusätzlich erklären, dass hier nun
nur noch vier statt der 6 Abfragen an die Datenbank gestellt werden, da einzelabfragen für die Adressen der Personen nur noch vier statt der 6 Abfragen an die Datenbank gestellt werden, da einzelabfragen für die Adressen der Personen
@ -620,15 +624,15 @@ und der Koautoren komplett entfallen.
Nach dem der Quellcode nochmal untersucht wurde, konnte man festellen, dass bei jeder Anfrage die gleiche Bedingung Nach dem der Quellcode nochmal untersucht wurde, konnte man festellen, dass bei jeder Anfrage die gleiche Bedingung
benötigt wurde. Da die Sicht nun explizit für dies Anfrage geschaffen wurde, wurde die Bedingungen nun direkt in Sicht benötigt wurde. Da die Sicht nun explizit für dies Anfrage geschaffen wurde, wurde die Bedingungen nun direkt in Sicht
mit integriert. Dies bedeutet eine Erweiterung der Sicht aus \ref{lst:sql-materialized-view} um mit integriert. Dies bedeutet eine Erweiterung der Sicht aus \autoref{lst:sql-materialized-view} um
\ref{lst:sql-materialized-view-ext} und das entfernen der Parameter aus dem SQL-Anfragen im Java-Code. \autoref{lst:sql-materialized-view-ext} und das entfernen der Parameter aus dem SQL-Anfragen im Java-Code.
\begin{lstlisting}[language=SQL,caption={SQL Materialized View Erweiterung},label=lst:sql-materialized-view-ext] \begin{lstlisting}[language=SQL,caption={SQL Materialized View Erweiterung},label=lst:sql-materialized-view-ext]
WHERE d.validuntil > NOW() WHERE d.validuntil > NOW()
AND d.ispublishedindb = true; AND d.ispublishedindb = true;
\end{lstlisting} \end{lstlisting}
Nach dem Anpassungen haben sich dann die Werte aus \ref{tbl:measure-materialized-view-ext} ergeben. Nach dem Anpassungen haben sich dann die Werte aus \autoref{tbl:measure-materialized-view-ext} ergeben.
\begin{table}[h!] \begin{table}[h!]
\centering \centering
@ -661,21 +665,21 @@ erzeugt, noch ohne eine Konvertierung der ermittelten Daten in das Objekt, steig
Wenn man nun noch die Konvertierung der Daten wieder einbaut, steigt die Laufzeit nochmal auf nun 82 ms. Wenn man nun noch die Konvertierung der Daten wieder einbaut, steigt die Laufzeit nochmal auf nun 82 ms.
Dies zeigt, alleine das erzeugen der Objekt kostet die meiste Zeit. Dies zeigt, alleine das erzeugen der Objekt kostet die meiste Zeit.
Bei der Verwendung des Hints \textit{openjpa.FetchPlan.FetchBatchSize} kann die Abfrage enorm verschlechtern. Wenn Bei der Verwendung des Hints \textit{openjpa.""FetchPlan.""FetchBatchSize} kann 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 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 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 \textit{map}"=Funktion wird dadurch verlängert. Laufzeit der Datenbankanfrage minimal verkürzt, aber die \textit{map}"=Funktion wird dadurch verlängert.
Das aktivieren der Cache-Optionen wie in \ref{sec:performance-investigation-application:caching-openjpa} oder in Das aktivieren der Cache"=Optionen wie in \autoref{sec:performance-investigation-application:caching-openjpa} oder in
\ref{sec:performance-investigation-application:caching-query} dargestellt, haben keine Auswirkung auf die Performance. \autoref{sec:performance-investigation-application:cached-query} dargestellt, haben keine Auswirkung auf die Performance.
Dies ist dadurch erklärbar, da keine Objekte durch das OpenJPA"=Framework erstellt werden, sondern erst in der Dies ist dadurch erklärbar, da keine Objekte durch das OpenJPA"=Framework erstellt werden, sondern erst in der
\textit{map}"=Funktion des eigenen Codes. \textit{map}"=Funktion des eigenen Codes.
Nun wird noch geprüft, welche Performance das parsen der Json-Informationen im Server benötigt. Im ersten Schritt wird Nun wird noch geprüft, welche Performance das parsen der Json"=Informationen im Server benötigt. Im ersten Schritt wird
die Parse-Funktion auskommentiert und die Seite nochmal aufgerufen. Durch diese Umstellung fällt die Laufzeit der die Parse-Funktion auskommentiert und die Seite nochmal aufgerufen. Durch diese Umstellung fällt die Laufzeit der
Datenermittlung auf circa 4 ms ab. Nun muss noch geprüft werden, welche Zeit nun der Client zum parsen der Datenermittlung auf circa 4 ms ab. Nun muss noch geprüft werden, welche Zeit nun der Client zum parsen der
\ac{Json}"=Daten benötigt. Hierfür werden die Daten in einem versteckten \textbf{span}"=Element hinterlegt, wie es im \textit{Json}"=Daten benötigt. Hierfür werden die Daten in einem versteckten \textbf{span}"=Element hinterlegt, wie es
Beispiel \ref{lst:jsf-datatable-json} zu sehen ist. Die hinterlegte \ac{CSS}"=Klasse ist zum auffinden der Elemente im \autoref{lst:jsf-datatable-json} zu sehen ist. Die hinterlegte \textit{CSS}"=Klasse ist zum auffinden der Elemente
für den späteren Javascript. Das \textbf{ajax}"=Element im Beispiel ist notwendig, damit bei einem Seitenwechsel die neu für den späteren Javascript. Das \textbf{ajax}"=Element im Beispiel ist notwendig, damit bei einem Seitenwechsel die neu
übertragenen Elemente in eine lesbare Form gebracht werden. übertragenen Elemente in eine lesbare Form gebracht werden.
@ -692,11 +696,11 @@ für den späteren Javascript. Das \textbf{ajax}"=Element im Beispiel ist notwen
</p:column> </p:column>
\end{lstlisting} \end{lstlisting}
Um nun die übertragenen \ac{Json}"=Daten in eine darstellbare Form zu bringen, benötigt man noch eine Um nun die übertragenen \textit{Json}"=Daten in eine darstellbare Form zu bringen, benötigt man noch eine
JavaScript"=Funktion. Diese Funktion \ref{lst:jsf-datatable-json-convert} wird ermittelt erst alle versteckten Elemente, JavaScript"=Funktion. Die Funktion aus \autoref{lst:jsf-datatable-json-convert} ermittelt erst alle versteckten
parsed den Inhalt und erstellt neue \ac{HTML}"=Elemente mit dem darzustellenden Inhalt. Zusätzlich wird noch eine Elemente, parsed den Inhalt und erstellt neue \textit{HTML}"=Elemente mit dem darzustellenden Inhalt. Zusätzlich wird
Zeitmessung mit eingebaut, um die Laufzeit am Client für das Rendern in der Konsole anzuzeigen. Die Funktion wird nun noch eine Zeitmessung mit eingebaut, um die Laufzeit am Client für das Rendern in der Konsole anzuzeigen. Die Funktion
direkt nach dem die Webseite fertig geladen wurde gerufen. wird nun direkt nach dem die Webseite fertig geladen wurde aufgerufen.
\begin{lstlisting}[language=javascript,caption={Wandeln von Json nach Html},label=lst:jsf-datatable-json-convert] \begin{lstlisting}[language=javascript,caption={Wandeln von Json nach Html},label=lst:jsf-datatable-json-convert]
function isEmpty(str) { function isEmpty(str) {
@ -744,32 +748,4 @@ durchgeführt werden. Daher werden nun die Laufzeiten am Server und am Client zu
Aufruf auf der Serverseite nun 70 ms und am Client sind es circa 13 ms. Dies bedeutet addiert kommt man mit dieser Aufruf auf der Serverseite nun 70 ms und am Client sind es circa 13 ms. Dies bedeutet addiert kommt man mit dieser
Lösung auf eine kürzere Laufzeit und weniger Last am Server. Lösung auf eine kürzere Laufzeit und weniger Last am Server.
%\mytodos{hier noch darauf eingehen, dass die Hauptarbeit nicht beim editieren sondern bei der Anzeige ist}
\mytodos{Hier könnte man auch den Query-Cache nochmal verwenden, da die anfragen nun fix wären}
\mytodos{Grundlagen zur Materialized-View noch hinterlegen} \mytodos{Grundlagen zur Materialized-View noch hinterlegen}
\section{Statische Webseiten}
\label{sec:performance-investigation-application:static-website}
Wenn man die Dokumentenliste als statische Webseiten ablegt, werden die Zugriffszeiten sehr kurz sein. Darüber hinaus
funktionieren in statische Webseiten aber keine Suche oder eine Sortierung. Die Sortierung könnte durch das erstellen
von statischen Seite aller Möglichkeiten der Sortierung emuliert werden, diese würde den notwendigen Speicherbedarf der
Webseite vervielfachen. Für die Suchanfragen ist dies nicht mehr möglich, da nicht alle Suchanfragen vorher definiert
werden können.
Die Umstellung der Suche auf Client!=Basis wäre noch eine Möglichkeit, dafür benötigen die Clients entsprechend
Leistung und es muss eine Referenzdatei erstellt werden, die alle Informationen über die Dokumente beinhaltet, nach der
gesucht werden kann.
Daher ist eine Umstellung auf statische Webseiten nicht sinnvoll.
\section{Client basierte Webseiten}
\label{sec:performance-investigation-application:client-side-rendering}
Als weitere Möglichkeit könnte man die Webseite so umbauen, dass die Daten erst im Nachgang über eine AJAX-Anfrage
ermittelt und die Sortierung und Aufteilung im Client durchgeführt wird. Hierbei wird aber je nach Datenmenge ein
großer Speicher am Client benötigt und die Rechenleistung wird auf den Client verschoben.
Dies wiederrum ist ein Vorteil für den Serverbetreiber, da durch die Verschiebung weniger Rechenleistung am Server
benötigt wird. Gleichzeitig würde man damit wiederrum schwächere Clients, wie Smartphones, aussperren, da bei diesem
die notwendige Rechenleistung fehlt, um die Webseite in annehmbarer Zeit darzustellen.

View file

@ -7,9 +7,18 @@ Nun werden die durchgeführten Anpassungen anhand ihre Effektivität betrachtet
diese eine Optimierung darstellen. Weiterhin werden die Nachteile der Anpassungen überprüft und und bei der Betrachtung diese eine Optimierung darstellen. Weiterhin werden die Nachteile der Anpassungen überprüft und und bei der Betrachtung
der Effektivität mit beachtet. 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 welchen Umfang
sich diese auswirkt. Des Weiteren wird die Art der Programmierung für die Abfragen betrachtet, ob es signifikante
Unterschiede in der Performance und der Abarbeitung ergibt. Als weitere Punkt werden die Abfragen an die Datenbank
untersucht, um zu ermitteln ob diese durch Umstellung verbessert werden können. Als letzten werden die Materialisierten
Sichten verwendet, um zu ermitteln, ob durch einen vorverdichteten und aufbereiteten Datenbestand die Abfragen
beschleunigt werden können.
\mytodos{Zusätzlich beschreiben welche Möglichkeiten man genau genutzt hat und warum bzw. warum nicht} \mytodos{Zusätzlich beschreiben welche Möglichkeiten man genau genutzt hat und warum bzw. warum nicht}
\section{Nutzerumfrage} \section{Nutzerumfrage}
\label{sec:evaluation:user-survey}
Zusätzlich war noch eine Befragung unter den Benutzer und den Entwicklern geplant. Da hierfür nur fünf Personen zur Zusätzlich war noch eine Befragung unter den Benutzer und den Entwicklern geplant. Da hierfür nur fünf Personen zur
Verfügung stehen, ist dies nicht zielführend. Daher ist die sinnvolle Alternative ein rein technischer Ansatz, der Verfügung stehen, ist dies nicht zielführend. Daher ist die sinnvolle Alternative ein rein technischer Ansatz, der
@ -18,15 +27,13 @@ gewählt wurde.
\section{Statische Webseiten} \section{Statische Webseiten}
\label{sec:evaluation:static-website} \label{sec:evaluation:static-website}
\mytodos{prüfen wohin damit, hier oder odch in 5 lassen}
Wenn man die Dokumentenliste als statische Webseiten ablegt, werden die Zugriffszeiten sehr kurz sein. Darüber hinaus Wenn man die Dokumentenliste als statische Webseiten ablegt, werden die Zugriffszeiten sehr kurz sein. Darüber hinaus
funktionieren in statische Webseiten aber keine Suche oder eine Sortierung. Die Sortierung könnte durch das erstellen funktionieren in statische Webseiten aber keine Suche oder eine Sortierung. Die Sortierung könnte durch das erstellen
von statischen Seite aller Möglichkeiten der Sortierung emuliert werden, diese würde den notwendigen Speicherbedarf der von statischen Seite aller Möglichkeiten der Sortierung emuliert werden, diese würde den notwendigen Speicherbedarf der
Webseite vervielfachen. Für die Suchanfragen ist dies nicht mehr möglich, da nicht alle Suchanfragen vorher definiert Webseite vervielfachen. Für die Suchanfragen ist dies nicht mehr möglich, da nicht alle Suchanfragen vorher definiert
werden können. werden können.
Die Umstellung der Suche auf Client!=Basis wäre noch eine Möglichkeit, dafür benötigen die Clients entsprechend Die Umstellung der Suche auf Client"=Basis wäre noch eine Möglichkeit, dafür benötigen die Clients entsprechend
Leistung und es muss eine Referenzdatei erstellt werden, die alle Informationen über die Dokumente beinhaltet, nach der Leistung und es muss eine Referenzdatei erstellt werden, die alle Informationen über die Dokumente beinhaltet, nach der
gesucht werden kann. gesucht werden kann.
@ -35,8 +42,6 @@ Daher ist eine Umstellung auf statische Webseiten nicht sinnvoll.
\section{Client basierte Webseiten} \section{Client basierte Webseiten}
\label{sec:evaluation:client-side-rendering} \label{sec:evaluation:client-side-rendering}
\mytodos{prüfen wohin damit, hier oder odch in 5 lassen}
Als weitere Möglichkeit könnte man die Webseite so umbauen, dass die Daten erst im Nachgang über eine AJAX-Anfrage Als weitere Möglichkeit könnte man die Webseite so umbauen, dass die Daten erst im Nachgang über eine AJAX-Anfrage
ermittelt und die Sortierung und Aufteilung im Client durchgeführt wird. Hierbei wird aber je nach Datenmenge ein ermittelt und die Sortierung und Aufteilung im Client durchgeführt wird. Hierbei wird aber je nach Datenmenge ein
großer Speicher am Client benötigt und die Rechenleistung wird auf den Client verschoben. großer Speicher am Client benötigt und die Rechenleistung wird auf den Client verschoben.
@ -45,11 +50,11 @@ Dies wiederrum ist ein Vorteil für den Serverbetreiber, da durch die Verschiebu
benötigt wird. Gleichzeitig würde man damit wiederrum schwächere Clients, wie Smartphones, aussperren, da bei diesem benötigt wird. Gleichzeitig würde man damit wiederrum schwächere Clients, wie Smartphones, aussperren, da bei diesem
die notwendige Rechenleistung fehlt, um die Webseite in annehmbarer Zeit darzustellen. die notwendige Rechenleistung fehlt, um die Webseite in annehmbarer Zeit darzustellen.
\section{Statistiken im PostgreSQL auswerten} \section{Auswertung der Ergebnisse vor und nach der Optimierung}
\label{sec:evaluation:result-optimization}
\section{Vergleich der Ergebnisse vor und nach der Optimierung}
\subsection{Caching im OpenJPA} \subsection{Caching im OpenJPA}
\label{sec:evaluation:result-optimization: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 in 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 Optimierungen hängt stark von der gewählten Cache"=Größe und der aufgerufenen Webseiten ab. Solange die Anfragen sich
@ -57,7 +62,7 @@ auf die gleichen Objekte beziehen und diese alle im Cache hinterlegt werden kön
hoch aus. Sobald bei den Anfragen aber häufig die zu ermittelnden Objekt sich unterscheiden und alte Objekte wieder hoch aus. Sobald bei den Anfragen aber häufig die zu ermittelnden Objekt sich unterscheiden und alte Objekte wieder
aus dem Cache entfernt werden, fällt die Performance"=Verbesserung immer geringer aus. aus dem Cache entfernt werden, fällt die Performance"=Verbesserung immer geringer aus.
Das entfernen der Objekte kann zwar umgangen werden, indem die häufig abgefragten Objekte gepinnt werden, was aber 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. 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 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 gestellt werden muss. Damit ist immer ein gewisser Grundbedarf notwendig, da sich der Speicher bis zum eingestellten
@ -67,7 +72,7 @@ zur Verfügung steht.
Hierbei ist aber noch zu beachten, dass die Optimierung durch den Cache nicht die Laufzeit der Abfragen in der Datenbank Hierbei ist aber noch zu beachten, dass die Optimierung durch den Cache nicht die Laufzeit der Abfragen in der Datenbank
enorm verringert hat, sondern die Laufzeit beim erstellen der Objekte im \textit{OpenJPA}"=Framework. Dies sieht man enorm verringert hat, sondern die Laufzeit beim erstellen der Objekte im \textit{OpenJPA}"=Framework. Dies sieht man
sehr gut schon bei der ersten Messung, wie in \autoref{lst:measure-ojpa-active}. Hierbei werden die Laufzeit in der sehr gut schon bei der ersten Messung, wie in \autoref{tbl:measure-ojpa-active}. Hierbei werden die Laufzeit in der
Datenbank im Schnitt um circa 5 ms reduziert, aber die komplette Webseite wird fast 100 ms schneller an den Client Datenbank im Schnitt um circa 5 ms reduziert, aber die komplette Webseite wird fast 100 ms schneller an den Client
ausgeliefert. Dies ist nur dadurch erklärbar, dass das erstellen und mit den Datenwerte zu befüllen mehr Zeit kostet, ausgeliefert. Dies ist nur dadurch erklärbar, dass das erstellen und mit den Datenwerte zu befüllen mehr Zeit kostet,
als das Objekt aus dem Cache zu ermitteln und zurückzugeben. als das Objekt aus dem Cache zu ermitteln und zurückzugeben.
@ -77,6 +82,7 @@ wenn der Großteil der Objekte im Cache gehalten werden kann. Bei Bedarf sollten
explizit im Cache aufgenommen und angepinnt werden. explizit im Cache aufgenommen und angepinnt werden.
\subsection{Cached Queries} \subsection{Cached Queries}
\label{sec:evaluation:result-optimization:cached-queries}
Die Optimierung über die gespeicherten Anfragen brachte keine Verbesserung hervor. Dies ist dadurch erklärbar, dass 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. Da in diesem Fall in der Tabelle für die diese Art nur Anfragen verwendet werden, die keinerlei Bedingungen besitzen. Da in diesem Fall in der Tabelle
@ -90,8 +96,9 @@ Dadurch ist dieser Cache für eine Performance"=Verbesserung in unseren Fall nic
\subsection{Caching in EJB} \subsection{Caching in EJB}
\subsection{Abfragen mit JPQL und Criteria API} \subsection{Abfragen mit JPQL und Criteria API}
\label{sec:evaluation:result-optimization:jpal-capi}
Bei dem Vergleich zwischen den 2 Abfragemöglichkeiten der \ac{JPQ} und der Criteria API konnte in der Art der Abfragen Bei dem Vergleich zwischen den 2 Abfragemöglichkeiten der \ac{JPQL} und der Criteria API konnte in der Art der Abfragen
kein Unterschied dargestellt werden. Die Abfragen der beiden Systeme sind auf der Datenbankseite komplett identisch. kein Unterschied dargestellt werden. Die Abfragen der beiden Systeme sind auf der Datenbankseite komplett identisch.
Auch in der Übertragung der Daten aus der Datenbank in die Java"=Objekte konnte keine Unterschied in der Art und Auch in der Übertragung der Daten aus der Datenbank in die Java"=Objekte konnte keine Unterschied in der Art und
Geschwindigkeit festgestellt werden. Geschwindigkeit festgestellt werden.
@ -112,9 +119,10 @@ Aufgrund dessen ist die Entscheidung der Technik für die Performance irrelevant
jeweiligen Einsatzzweck besser beziehungsweise einfacher zu programmieren ist. Das setzen der richtigen Hints wiederrum jeweiligen Einsatzzweck besser beziehungsweise einfacher zu programmieren ist. Das setzen der richtigen Hints wiederrum
ist in beiden Fällen äußerst wichtig. Explizit der EagerFetchMode muss vorher darüber nachgedacht werden, wie viele ist in beiden Fällen äußerst wichtig. Explizit 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 abhängige Objekttypen es zu dieser Klasse gibt, welche dazu geladen werden sollen und von welcher Anzahl an Objekte
ausgegangen werden kann. Gerade bei ein größeren Anzahl lohnt es sich den Hit auf \textit{parallel} zu setzen. ausgegangen werden kann. Gerade bei ein größeren Anzahl lohnt es sich den Hint auf \textit{parallel} zu setzen.
Gleiches gilt den Hint SubclassFetchMode, dieser steuert die Abfragen im falle von abgeleitet Klassen. Gleiches gilt den Hint SubclassFetchMode, dieser steuert die Abfragen im falle von abgeleitet Klassen.
\subsection{Materialized View} \subsection{Materialized View}
\label{sec.evaluation:result-optimization:materialized-view}
\mytodos{hier weiter machen} \mytodos{hier weiter machen}

View file

@ -63,6 +63,24 @@
urldate = {2024-09-12} urldate = {2024-09-12}
}, },
@online{PostgreS39:online,
author = {},
title = {PostgreSQL: Documentation: 16: 54.27. pg\_stats},
url = {https://www.postgresql.org/docs/current/view-pg-stats.html},
month = {},
year = {},
urldate = {2024-09-14}
},
@online{PostgreS12:online,
author = {},
title = {PostgreSQL: Documentation: 16: CREATE STATISTICS},
url = {https://www.postgresql.org/docs/16/sql-createstatistics.html},
month = {},
year = {},
urldate = {2024-09-14}
},
@online{AspNetCore:2024:MVC, @online{AspNetCore:2024:MVC,
year = 2024, year = 2024,
url = {https://learn.microsoft.com/de-de/aspnet/core/fundamentals/middleware/?view=aspnetcore-8.0}, url = {https://learn.microsoft.com/de-de/aspnet/core/fundamentals/middleware/?view=aspnetcore-8.0},

Binary file not shown.

View file

@ -44,7 +44,6 @@
%************************************************************************* %*************************************************************************
\addbibresource{Expose-ref.bib} \addbibresource{Expose-ref.bib}
%************************************************************************* %*************************************************************************
% GO!GO!GO! MOVE IT! % GO!GO!GO! MOVE IT!
%************************************************************************* %*************************************************************************
@ -52,6 +51,12 @@
\frenchspacing \frenchspacing
\raggedbottom \raggedbottom
\selectlanguage{ngerman} % ngerman, american \selectlanguage{ngerman} % ngerman, american
%*************************************************************************
% Hyphenation - scheinbar erst nach Sprachselektion, sonst funktioniert es nicht
%*************************************************************************
\hyphenation{
Spei-cher-be-darf
}
%\renewcommand*{\bibname}{new name} %\renewcommand*{\bibname}{new name}
%\setbibpreamble{} %\setbibpreamble{}
\pagenumbering{roman} \pagenumbering{roman}