diff --git a/chapters/thesis/chapter05.tex b/chapters/thesis/chapter05.tex index b1d8b01..4e3156a 100644 --- a/chapters/thesis/chapter05.tex +++ b/chapters/thesis/chapter05.tex @@ -222,7 +222,7 @@ Der Vergleich zeigt, dass der Cache eine gute Optimierung bringt, aber dies nur wieder die gleichen Objekte ermittelt werden. Sobald die Anfragen im Wechsel gerufen werden oder einfach nur die Menge der Objekte den Cache übersteigt, fällt die Verbesserung geringer aus. -\section{cached queries} +\section{Cached Queries} \label{sec:performance-investigation-application:cached-query} Über die Einstellung \textit{openjpa.""jdbc.""QuerySQLCache} wird der Cache für abfragen aktiviert. Hierbei können @@ -473,80 +473,6 @@ Einstellung \textit{openjpa.""FetchPlan.""EagerFetchMode} liefert auch hier Opti \textit{parallel} gestellt wird. Hier wird ebenfalls die Anzahl der Anfragen reduziert und damit auch die Geschwindigkeit optimiert. -\section{Optimierung der Abfrage} -\label{sec:performance-investigation-application:optimizing-query} - -Für die Optimierung der Abfrage werden diese zuerst mit \textit{explain}, wie in \autoref{lst:explain-diagnostic} -dargestellt, untersuchen. Für die einfachere Diagnose, wird der erstellte Plan Mithilfe von pev2 -\citep{GitHubda51:online} visualisiert. - -\begin{lstlisting}[language=SQL,caption={Explain für Diagnose},label=lst:explain-diagnostic] -explain (analyze, verbose, buffers, summary, format json) -select -from - public.document t0 - left outer join public.historicalperson t1 on t0.authorperson_id = t1.id - left outer join public.sitecity t5 on t0.city_id = t5.id - left outer join public.appuser t6 on t0.editor_id = t6.id - left outer join public.extendedbiography t2 on t1.extendedbiography_id = t2.id - left outer join public.sitecity t3 on t1.sitecity_birth_id = t3.id - left outer join public.sitecity t4 on t1.sitecity_death_id = t4.id - left outer join public.appuserrole t7 on t6.appuserrole_id = t7.id -where (t0.validuntil > NOW() - and t0.ispublishedindb = true) -order by startyear DESC, startmonth DESC, startday DESC -limit 400; -\end{lstlisting} - -Die erstellte Visualisierung der Abfrage ist in \autoref{fig:explain-visualize} zu sehen. In der Visualisierung wurde -die Darstellung der Kosten gewählt, da ein Vergleich auf Basis der Zeit sehr schwierig ist und von äußeren Faktoren -abhängt, wie zum Beispiel dem Cache. Die Kosten sind stabiler und hängen in erster Linie vom Datenbestand ab. - -\begin{figure}[h!] - \includegraphics[width=\linewidth]{gfx/chapter05_ExplainVisualize.png} - \caption{Visualisierung EXPLAIN} - \label{fig:explain-visualize} -\end{figure} - -In der Graphik ist zu sehen, dass zum einen die Hauptkosten im untersten Knoten \textit{Seq Scan} und einen der -obersten Knoten dem \textit{HashAggregate} liegen. Zusätzlich sieht man anhand der stärke von den Verbindungslinien der -Knoten, dass die Menge der Datensätze enorm hoch ist und dieser sich bis zum obersten Knoten durchzieht. Dies -bedeutet, dass die Einschränkung des Datenbestandes erst am Ende der Abfrage durchgeführt wird und diesbezüglich die -Dauer der Abfrage linear mit den Inhalt der \textit{document}"=Tabelle zusammenhängt. Des Weiteren wird für keine -Tabelle ein \textit{Index Scan} verwendet, sondern immer mit einem \textit{Seq Scan} gearbeitet, da durch das ermitteln -des kompletten Datenbestandes der Optimizer entscheidet, dass der komplette Scan der Tabelle kostengeringer ist, als -die Verwendung eines der vorhandenen Indexe. Dies kann durch den Befehl \lstinline[language=SQL]|SET enable_seqscan = off| -sehr einfach verifiziert werden. Damit wird die Verwendung von \textit{Seq Scan} deaktiviert und es wird dann ein -\textit{Index Scan} verwendet. Wenn man nun beide Pläne vergleicht sieht man die Erhöhung der Kosten bei der Verwendung -von \textit{Index Scan}. - -Die beste Optimierung hierbei ist, die Menge der Datensätze so früh wie möglich einzuschränken. Da die Verwendung von -\textit{order by} innerhalb eines Sub"=Selects nicht erlaubt ist, verwenden wir hierfür eine \textit{Common Table -Expression}, wie es in \autoref{lst:explain-optimize-cte} zu sehen ist. Zusätzlich wurde noch ein Index auf der -\textit{document}"=Tabelle für die Spalten der Bedingung und der Sortierung gesetzt, wie in -\autoref{lst:explain-optimize-cte-idx} zur sehen. - -\begin{lstlisting}[language=SQL,caption={Optimierung mit Common Table Expression},label=lst:explain-optimize-cte] -with doc_limit as ( - select id - from public.document - where validuntil > now() - and ispublishedindb = true - order by startyear desc, startmonth desc, startday desc - limit 400 -) -select * -from doc_limit t - join public.document t0 on t0.id = t.id -order by t0.startyear desc, t0.startmonth desc, t0.startday desc -\end{lstlisting} - -\begin{lstlisting}[language=SQL,caption={Index für Common Table Expression},label=lst:explain-optimize-cte-idx] -create index idx_document_with_stmt on document using btree - ( ispublishedindb, validuntil, startyear desc, startmonth desc - , startday desc, id ); -\end{lstlisting} - \section{Materialized Views} \label{sec:performance-investigation-application:materialized-views} @@ -559,10 +485,12 @@ Der größte Nachteil dieser Sichten ist, dass sie zyklisch oder bei Datenänder 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 ignoriert werden. -In diesem Test wurde die von Herrn Holstein bereitgestellte Materialized View inklusive der Trigger und der -\textit{SearchDocument}"=Klasse verwendet. Wie in \autoref{lst:sql-materialized-view} zu sehen, wurden zur +\mytodos{hier nochmal die referenz auf wedekind-repo einbauen} + +In diesem Test wurde die aktuelle Implementierung aus dem Wedekind"=Projekt der Materialized View inklusive der Trigger +und der \textit{SearchDocument}"=Klasse übernommen. Wie in \autoref{lst:sql-materialized-view} zu sehen, wurden zur Standard"=Abfrage, die sonst zusätzlichen Abfragen als direkte Sub"=Selects mit integriert. Der Datenbestand dieser -Sub"=Selects, wird im Json"=Format angegeben, damit bei den Koautoren und den Adressen mehrere Datensätze in einer +Sub"=Selects, wird im Json"=Format angegeben, damit bei den Koautoren und den Adressen mehrere Datensätze in einer Zeile zurückgegeben werden können. Ohne diese Technik würde sich die Anzahl der Dokumente vervielfachen. \begin{lstlisting}[language=SQL,caption={SQL Materialized View},label=lst:sql-materialized-view] @@ -647,7 +575,7 @@ LEFT JOIN sitecity sc ON sc.id = d.city_id; \end{lstlisting} Zusätzlich zur View, werden noch die Indexe aus \autoref{lst:sql-materialized-view-index} erstellt. Diese werden für -für eine bessere Performance der Abfrage benötigt. +eine bessere Performance der Abfrage benötigt. \begin{lstlisting}[language=SQL,caption={SQL Materialized View},label=lst:sql-materialized-view-index] CREATE INDEX idx_searchdocument_documentid @@ -671,8 +599,8 @@ CREATE INDEX idx_searchdocument_documentcategory ON searchdocument (documentcategory); \end{lstlisting} -Für die Darstellung wurden die aktuell vorhandenen Elemente die die Liste der Dokumente anzeigt kopiert und auf die -neue SearchDocument"=Klasse angepasst. +Für die Datenermittlung wurden die notwendigen Teile aus dem Wedekind"=Projekt kopiert. Bei der Darstellung wurden die +vorhanden Elemente die die Liste der Dokumente anzeigt kopiert und auf die \textit{SearchDocument}"=Klasse angepasst. % document, first/last, documentaddresseeperson, documentcoauthorperson, documentfacsimile und count % document, count, first/last @@ -697,11 +625,11 @@ neue SearchDocument"=Klasse angepasst. \label{tbl:measure-materialized-view} \end{table} -Wie in \autoref{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 eine Verbesserung 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 -nur noch vier statt der 6 Abfragen an die Datenbank gestellt werden, da einzelabfragen für die Adressen der Personen -und der Koautoren komplett entfallen. +nur noch vier statt der 6 Abfragen an die Datenbank gestellt werden, da die Einzelabfragen für die Adressen der +Personen und der Koautoren komplett entfallen. Nach dem der Quellcode nochmal untersucht wurde, konnte man festellen, dass bei jeder Anfrage die gleiche Bedingung benötigt wurde. Da die Sicht nun explizit für dies Anfrage geschaffen wurde, wurde die Bedingungen nun direkt in die @@ -724,8 +652,8 @@ Nach dem Anpassungen haben sich dann die Werte aus \autoref{tbl:measure-material \hline \# & min & avg & max & \#"=avg & avg & start & stop & diff & min & avg & max & min & avg & max \\ \hline - 1 & 241 & 348 & 859 & 16.8 & xxx & 896.0 & 932.4 & xxxx & 232 & 331 & 803 & 132 & 174 & 334 \\ % 168 - - 2 & 164 & 194 & 225 & 9.0 & xxx & 933.3 & 935.9 & xxxx & 154 & 185 & 215 & 79 & 99 & 117 \\ % 258 - + 1 & 241 & 348 & 859 & 16.8 & xxx & 896.0 & 932.4 & 36.4 & 232 & 331 & 803 & 132 & 174 & 334 \\ % 168 - + 2 & 164 & 194 & 225 & 9.0 & xxx & 933.3 & 935.9 & 2.6 & 154 & 185 & 215 & 79 & 99 & 117 \\ % 258 - 3 & 147 & 161 & 179 & 9.0 & xxx & 935.8 & 938.8 & 3.0 & 139 & 152 & 167 & 68 & 77 & 86 \\ % 348 - 4 & 135 & 145 & 183 & 9.0 & xxx & 939.4 & 936.0 & -3.4 & 127 & 137 & 174 & 70 & 73 & 75 \\ % 438 - 5 & 126 & 137 & 154 & 9.0 & xxx & 936.1 & 939.1 & 3.0 & 118 & 129 & 143 & 66 & 72 & 79 \\ % 528 - @@ -756,13 +684,15 @@ Das aktivieren der Cache"=Optionen wie in \autoref{sec:performance-investigation Dies ist dadurch erklärbar, da keine Objekte durch das OpenJPA"=Framework erstellt werden, sondern erst in der \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 -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 -\textit{Json}"=Daten benötigt. Hierfür werden die Daten in einem versteckten \textbf{span}"=Element hinterlegt, wie es -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 -übertragenen Elemente in eine lesbare Form gebracht werden. +Wie schon ermittelt, benötigt das erstellen der Objekte den Großteil der Zeit für die Datenermittlung. Daher wurde die +bereitgestellt Klasse betrachtet und die wie mit Herrn Tobias Holstein ausgemacht, der JsonParser nochmal genauer +untersucht. Im ersten Schritt wird die Parse"=Funktion entfernt und die Seite nochmals 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 \textit{Json}"=Daten benötigt. Hierfür werden die Daten in einem versteckten +\textbf{span}"=Element hinterlegt, wie es 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 gleiche Interpreter"=Funktion für die \textit{Json}"=Daten aufgerufen +wird, wie beim laden der Webseite. \begin{lstlisting}[language=xml,caption={DataTable mit Json},label=lst:jsf-datatable-json] @@ -777,11 +707,11 @@ für den späteren Javascript. Das \textbf{ajax}"=Element im Beispiel ist notwen \end{lstlisting} -Um nun die übertragenen \textit{Json}"=Daten in eine darstellbare Form zu bringen, benötigt man noch eine -JavaScript"=Funktion. Die Funktion aus \autoref{lst:jsf-datatable-json-convert} ermittelt erst alle versteckten -Elemente, parsed den Inhalt und erstellt neue \textit{HTML}"=Elemente mit dem darzustellenden Inhalt. Zusätzlich wird -noch eine Zeitmessung mit eingebaut, um die Laufzeit am Client für das Rendern in der Konsole anzuzeigen. Die Funktion -wird nun direkt nach dem die Webseite fertig geladen wurde aufgerufen. +Die Interpreter"=Funktion, welche in JavaScript geschrieben ist, wird benötigt um die ie übertragenen +\textit{Json}"=Daten in eine darstelle Form zu bringen. Die Funktion aus dem \autoref{lst:jsf-datatable-json-convert} +ermittelt erst alle versteckten Elemente, parsed den Inhalt und erstellt neue \textit{HTML}"=Elemente mit dem +darzustellenden Inhalt. Zusätzlich wird noch eine Zeitmessung mit eingebaut, um die Laufzeit am Client für das Rendern +in der Konsole anzuzeigen. Die Funktion wird nun direkt nach dem die Webseite fertig geladen wurde aufgerufen. \begin{lstlisting}[language=javascript,caption={Wandeln von Json nach Html},label=lst:jsf-datatable-json-convert] function isEmpty(str) { @@ -829,4 +759,93 @@ 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 Lösung auf eine kürzere Laufzeit und weniger Last am Server. -\mytodos{Grundlagen zur Materialized-View noch hinterlegen} +\section{Optimierung der Abfrage} +\label{sec:performance-investigation-application:optimizing-query} + +Für die Optimierung der Abfrage werden diese zuerst mit \textit{explain}, wie in \autoref{lst:explain-diagnostic} +dargestellt, untersuchen. Für die einfachere Diagnose, wird der erstellte Plan Mithilfe von pev2 +\citep{GitHubda51:online} visualisiert. + +\begin{lstlisting}[language=SQL,caption={Explain für Diagnose},label=lst:explain-diagnostic] +explain (analyze, verbose, buffers, summary, format json) +select +from + public.document t0 + left outer join public.historicalperson t1 on t0.authorperson_id = t1.id + left outer join public.sitecity t5 on t0.city_id = t5.id + left outer join public.appuser t6 on t0.editor_id = t6.id + left outer join public.extendedbiography t2 on t1.extendedbiography_id = t2.id + left outer join public.sitecity t3 on t1.sitecity_birth_id = t3.id + left outer join public.sitecity t4 on t1.sitecity_death_id = t4.id + left outer join public.appuserrole t7 on t6.appuserrole_id = t7.id +where (t0.validuntil > NOW() + and t0.ispublishedindb = true) +order by startyear DESC, startmonth DESC, startday DESC +limit 400; +\end{lstlisting} + +Die erstellte Visualisierung der Abfrage ist in \autoref{fig:explain-visualize} zu sehen. In der Visualisierung wurde +die Darstellung der Kosten gewählt, da ein Vergleich auf Basis der Zeit sehr schwierig ist und von äußeren Faktoren +abhängt, wie zum Beispiel dem Cache. Die Kosten sind stabiler und hängen in erster Linie vom Datenbestand ab. + +\begin{figure}[h!] + \includegraphics[width=\linewidth]{gfx/chapter05_ExplainVisualize.png} + \caption{Visualisierung EXPLAIN} + \label{fig:explain-visualize} +\end{figure} + +In der Graphik ist zu sehen, dass zum einen die Hauptkosten im untersten Knoten \textit{Seq Scan} und einen der +obersten Knoten dem \textit{HashAggregate} liegen. Zusätzlich sieht man anhand der stärke von den Verbindungslinien der +Knoten, dass die Menge der Datensätze enorm hoch ist und dieser sich bis zum obersten Knoten durchzieht. Dies +bedeutet, dass die Einschränkung des Datenbestandes erst am Ende der Abfrage durchgeführt wird und diesbezüglich die +Dauer der Abfrage linear mit den Inhalt der \textit{document}"=Tabelle zusammenhängt. Des Weiteren wird für keine +Tabelle ein \textit{Index Scan} verwendet, sondern immer mit einem \textit{Seq Scan} gearbeitet, da durch das ermitteln +des kompletten Datenbestandes der Optimizer entscheidet, dass der komplette Scan der Tabelle kostengünstiger ist, als +die Verwendung eines der vorhandenen Indexe. Dies kann durch den Befehl \lstinline[language=SQL]|SET enable_seqscan = off| +sehr einfach verifiziert werden. Damit wird die Verwendung von \textit{Seq Scan} deaktiviert und es wird dann ein +\textit{Index Scan} verwendet. Wenn man nun beide Pläne vergleicht sieht man die Erhöhung der Kosten bei der Verwendung +von \textit{Index Scan}. + +Die beste Optimierung hierbei ist, die Menge der Datensätze so früh wie möglich einzuschränken. Da die Verwendung von +\textit{order by} innerhalb eines Sub"=Selects nicht erlaubt ist, verwenden wir hierfür eine \textit{Common Table +Expression}, wie es in \autoref{lst:explain-optimize-cte} zu sehen ist. Zusätzlich wurde noch ein Index auf der +\textit{document}"=Tabelle für die Spalten der Bedingung und der Sortierung gesetzt, wie in +\autoref{lst:explain-optimize-cte-idx} zur sehen, damit in der \textit{Common Table Expression} nur der Index verwendet +werden kann und kein zusätzlicher Zugriff in die Tabelle notwendig ist. + +\begin{lstlisting}[language=SQL,caption={Optimierung mit Common Table Expression},label=lst:explain-optimize-cte] +with doc_limit as ( + select id + from public.document + where validuntil > now() + and ispublishedindb = true + order by startyear desc, startmonth desc, startday desc + limit 400 +) +select * +from doc_limit t + join public.document t0 on t0.id = t.id +order by t0.startyear desc, t0.startmonth desc, t0.startday desc +\end{lstlisting} + +\begin{lstlisting}[language=SQL,caption={Index für Common Table Expression},label=lst:explain-optimize-cte-idx] +create index idx_document_with_stmt on document using btree + ( ispublishedindb, validuntil, startyear desc, startmonth desc + , startday desc, id ); +\end{lstlisting} + +Mit diesen Umstellungen erkennt man nun, dass die Kosten entsprechend gefallen sind. Ebenfalls konnten die Laufzeit um +mehr als den Faktor drei reduziert werden. Die Optimierung ist in \autoref{fig:explain-visualize-with} sehr deutlich +an dein dünneren Verbindungslinien zwischen den Knoten und der Umstellung von einigen \textit{Seq Scan} zu +\textit{Index Scan} ersichtlich. Zeitgleich ist auch der teure \textit{HashAggregate} nicht mehr im Abfrageplan +vorhanden. + +\begin{figure}[h!] + \includegraphics[width=\linewidth]{gfx/chapter05_ExplainVisualize_with.png} + \caption{Visualisierung EXPLAIN with} + \label{fig:explain-visualize-with} +\end{figure} + +Bei der Untersuchung der Abfrage zur Materialized View ist direkt herausgekommen, dass hier keine Optimierung mehr +möglich ist, da durch die definierten Index bei den aktuell möglichen Sortierkriterien direkt ein \textit{Index Scan} +verwendet wird. Damit ist der schnellstmögliche Zugriff gegeben. diff --git a/chapters/thesis/chapter06.tex b/chapters/thesis/chapter06.tex index 2349f63..e5e32a8 100644 --- a/chapters/thesis/chapter06.tex +++ b/chapters/thesis/chapter06.tex @@ -91,10 +91,35 @@ werden. Dies ist der Grund warum diese Anfragen in diesem Cache nicht gespeicher Dadurch ist dieser Cache für eine Performance"=Verbesserung in unseren Fall nicht verwendbar. +\subsection{Caching mit Ehcache} +\label{sec:evaluation:result-optimization:ehcache} + +\mytodos{fehlt noch} +Mit dem Ehcache konnte eine Verbesserung in der Performance erzielt werden. Im Vergleich zum Cache von OpenJPA sind +die Verbesserung sehr ähnlich. Die Standardwerte dieses Caches sind gut vordefiniert, es wird für den aktuellen Fall +keine Anpassung benötigt um eine gute Performance zu bekommen. Hierbei ist natürlich das gleiche Problem wie in anderen +Caches, dass beim erreichen der Grenzen, alte Objekte entfernt werden müssen. + +Nach aktueller Beobachtung scheint die Verwaltung im Ehcache effizienter gestaltet zu sein, als die des OpenJPA"=Caches. +Im Falle des Ehcache ist die interne Verwaltung auf mehrere Caches aufgebaut, dies ist daran zu sehen, dass in der +Standardkonfiguration jede Klasse ihren eigenen Cache besitzt. Diese können einzeln konfiguriert und diagnostiziert +werden, um diese genau auf die jeweiligen Bedürfnisse der Objekte anzupassen. + +Im Falle der Verwendung des Caches, ist auch hier gut zu sehen, dass der Speicheranstieg bei der Verwendung des Caches +sehr gering ist, was den Schluss zu lässt, dass der Cache nur zu einem kleinen + +Durch die effizienter Verwendung des Speichers, ist der Ehcache die bessere Alternative zum OpenJPA"=Cache. Dieser ist +auch schon für kleinere Serverkonfigurationen gut verwendbar. Hierbei ist nur abzuwägen, mit welcher Größe der Cache +bereitgestellt werden kann, was direkt am verfügbaren Arbeitsspeicher abhängt. + \subsection{Caching in EJB} \label{sec:evaluation:result-optimization:ejb} -\mytodos{fehlt noch} +Bei der Erweiterung des EJB konnte keine Verbesserung in der Performance festgestellt werden. Dies liegt daran, dass +im EJB"=Cache die Provider beinhaltet, aber keine Daten"=Objekte. Dadurch kann der Cache das ermitteln der Objekte +nicht optimieren. + +Aufgrund dessen ist der EJB"=Cache nicht für eine Performance"=Verbesserung nutzbar. \subsection{Abfragen mit JPQL und Criteria API} \label{sec:evaluation:result-optimization:jpal-capi} @@ -121,9 +146,26 @@ jeweiligen Einsatzzweck besser beziehungsweise einfacher zu programmieren ist. D 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 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 dimensionierten Abfragen im falle von abgeleitet Klassen. \subsection{Materialized View} -\label{sec.evaluation:result-optimization:materialized-view} +\label{sec:evaluation:result-optimization:materialized-view} -\mytodos{hier weiter machen} \ No newline at end of file +\mytodos{hier weiter machen} +Mit der Verwendung der Materialisierten Sichten können +Die Idee der Materialisierten Sichten ist simple aber sehr effizient, gerade für einen Datenbestand der häufig gelesen +und selten verändert wird. Hierbei werden komplexe Abfragen einmalig ausgeführt und das Ergebnis intern +zwischengespeichert wird. Für alle weiteren Aufrufe, werden die Daten nun aus der Sicherung gelesen. Technisch gesehen +könnte dies auch selbständig implementiert werden, in dem zyklisch oder ereignisgesteuert das Ergebnis der Abfrage in +eine Tabelle gespeichert wird. + +Der Vorteil der Materialisierten Sichten ist, dass es einfach zu implementieren ist, eine geringere Fehleranfälligkeit +aufweist und , da alles über die reine Sichtdefinition erstellt wird. Ebenfalls + +% verweisen auf doppelte Speicherung, ist zwar im cache das gleich, aber abzuwägen an welcher Stelle "mehr" zur +% verfügung steht bzw. welcher Part günstiger in der Bereitstellung ist + +\subsection{Optimierung der Abfrage} +\label{sec:evaluation:result-optimization:optimize-query} + +\mytodos{fehlt noch} diff --git a/thesis.pdf b/thesis.pdf index f986903..9f65f49 100644 Binary files a/thesis.pdf and b/thesis.pdf differ