Daily CheckIn
This commit is contained in:
parent
e096c14dcc
commit
0d7fc1ae62
11 changed files with 272 additions and 161 deletions
55
.vscode/settings.json
vendored
55
.vscode/settings.json
vendored
|
@ -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"
|
||||||
],
|
],
|
||||||
|
|
|
@ -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}
|
||||||
|
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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]}},
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -23,13 +23,13 @@ circa 60 Aufrufe des Scripts benötigt, damit der Server nicht mehr reagiert. Hi
|
||||||
in der Log-Datei protokolliert und der Server verwendet nun circa 4700 MB RSS. Bei allen Tests war noch mehr als die
|
in der Log-Datei protokolliert und der Server verwendet nun circa 4700 MB RSS. Bei allen Tests war noch mehr als die
|
||||||
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.
|
|
||||||
|
|
|
@ -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}
|
|
@ -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},
|
||||||
|
|
BIN
thesis.pdf
BIN
thesis.pdf
Binary file not shown.
|
@ -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}
|
||||||
|
|
Loading…
Reference in a new issue