\documentclass[aspectratio=169]{beamer}
\graphicspath{ {./gfx/} }
\input{beamer-config}
\usetheme{cleangreen}

\input{marco-galster-config}
\addbibresource{expose-ref.bib}

%\usepackage{fourier}
\usepackage{array}
\usepackage{makecell}
\renewcommand\theadalign{bc}
\renewcommand\theadfont{\bfseries}
\renewcommand\theadgape{\Gape[4pt]}
\renewcommand\cellgape{\Gape[4pt]}

% ACHTUNG: Damit sich die Datei sauber im Visual Studio Code übersetzten lässt, muss in den Benutzer-Einstellungen
%   das Element "latex-workshop.latex.tools" aufgenommen werden und der erscheinende Eintrag für latexmk bei den
%   args am Anfang um den folgenden Eintrage erweitert werden:
%       "-shell-escape"
% TODO


\title{\myTitle}
%\subtitle{}
\author[M. Galster]{\myName}
\footlinetext{\insertshortauthor \hspace{4em} Multi"=Layer Optimization Strategies for Enhanced Performance in Digital Editions}
\institute{Universität~in~Hagen,~Deutschland}
\date{07. November 2024}

\tikzset{
    every axis/.style={
        %%width=\textwidth,height=\textheight,
        xlabel={Aufruf},
        ylabel={Laufzeit [ms]},
        enlargelimits=0.05,
        ymin=0, %ymax=2100,
        xtick={0,1,2,3,4,5}, %Ticks explizit angeben, dass bei grpßerer Darstellung nicht Zwischenticks existieren
        legend pos=north east,
        ymajorgrids=true,
        grid style=dashed,
    },
}

\begin{document}
\selectlanguage{ngerman}

% - Vergleich mit barchart nicht die Tabellen
% - Prozess zeigen was wo gemessen wird, also was genau wurde wo verändert. hier könnte man die Schichtdarstellung nutzen
%    und dort markieren, was genau verändert wurde

% -- SLIDE -- Title
% 1. Titelfolie
\begin{frame}[plain]
\titlepage
\end{frame}

% -- SLIDE -- TOC
% 2. Agenda
\begin{frame}[c]
    \frametitle{Agenda}

    %left space
    \begin{addmargin*}{2.5em}
        %enhance line space
        \begin{spacing}{1}
            \parbox{\linewidth}{%
                \tableofcontents
            }
        \end{spacing}
    \end{addmargin*}

    \addtocounter{framenumber}{-1}

\end{frame}
\def\showHorizontalNavBar{True}

% -- SLIDES --
% 3. Einleitung (Warum ist das Thema relevant, Ziel der Arbeit, Ergebnis mit dem nicht gerechnet hat)
\section{Einleitung}
\begin{frame}[c]
    \frametitle{Problemstellung}
    \begin{columns}
        \column{.5\textwidth}
        \centering
        \includegraphics[width=0.9\textwidth]{Webseite_FrankWedekind}

        \column{.5\textwidth}        
        \begin{itemize}
            \item Eine webbasierte Anwendung der Frank Wedekind Briefedition 
            \item Performance Probleme bei der Abfrage der Briefe sowie der Recherchen der Korrespondenzen
            \item Entsprechend geringere Akzeptanz der Anwendung
        \end{itemize}
    \end{columns}
\end{frame}

% 4. Forschungsgegenstand (Thema einführen durch Vorstellung Forschungsgegenstand)
\begin{frame}[c]
    \frametitle{Ablauf einer Web-Anfrage}
    \begin{figure}[centered]
        \begin{tikzpicture}[scale=.55,transform shape,node distance=4em,
            block/.style={rectangle, rounded corners,minimum width=3cm,minimum height=.5cm,text centered, draw=black,fill=green!30},
            lineArrow/.style={arrows={-Latex[length=5pt 3 0]}},
            every fit/.style={inner sep=.4em,draw}
        ]
            \node (browser) [block] {Webbrowser};
            \node (fitClient) [rounded corners,fit=(browser)] {};
            \node [left] at (fitClient.west) {Client};
            
            \node (JSF) [block,below of=browser,node distance=5em] {Java Server Faces};
            \node (EJB) [block,below of=JSF] {Enterprise Java Beans};
            \node (JPA) [block,below of=EJB] {Java Persistance API};
            \node (openJPA) [block, below of=JPA] {OpenJPA Cache};
            \node (fitGlassfish) [rounded corners,fit=(JSF) (EJB) (JPA) (openJPA)] {};
            \node [left] at (fitGlassfish.west) [text width=1.5cm] {GlassFish/ Payara};
    
            \node (memoryBuffers) [block, below of=openJPA] {Memory Buffers};
            \node (services) [block, right of=memoryBuffers, xshift=2cm] {Services};
            \node (database) [block, below of=memoryBuffers] {Database};
            \node (fitPostgreSQL) [rounded corners,fit=(memoryBuffers) (services) (database)] {};
            \node [left] at (fitPostgreSQL.west) {PostgreSQL};
    
            \node (fitServer) [rounded corners,fit=(fitGlassfish) (fitPostgreSQL),inner xsep=3em] {};
            \node [left] at (fitServer.west) {Server};
    
            \draw[lineArrow] (browser)--(JSF);
            \draw[lineArrow] (JSF)--(EJB);
            \draw[lineArrow] (EJB)--(JPA);
            \draw[lineArrow] (JPA)--(openJPA);
            \draw[lineArrow] (openJPA)--(memoryBuffers);
            \draw[lineArrow] (memoryBuffers)--(database);
            \draw[lineArrow] (services)|-(database);
        \end{tikzpicture}
        \label{fig:webrequest}
    \end{figure}
\end{frame}

\begin{frame}[c]
    \frametitle{Anpassungen}
    \begin{columns}
        \column{0.5\textwidth}
        \onslide<1>{
        \begin{itemize}
            \item Caching EJB
        \end{itemize}
        }
        \onslide<2>{
        \begin{itemize}
            \item Abfragen in JPQL
            \item Abfragen in Criteria API
        \end{itemize}
        }
        \onslide<3>{
        \begin{itemize}
            \item Caching in OpenJPA
            \item Cached Queries
            \item Caching mit Ehcache
        \end{itemize}
        }
        \onslide<4>{
        \begin{itemize}
            \item Materialized Views
            \item Optimierung der Abfrage
        \end{itemize}
        }


        \column{0.5\textwidth}
        \begin{figure}[centered]
            \begin{tikzpicture}[scale=.55,transform shape,node distance=4em,
                block/.style={rectangle, rounded corners,minimum width=3cm,minimum height=.5cm,text centered, draw=black,fill=green!30},
                selected/.style={rectangle, rounded corners,minimum width=3cm,minimum height=.5cm,text centered, draw=black,fill=blue!30},
                halfselected/.style={rectangle, rounded corners,minimum width=3cm,minimum height=.5cm,text centered, draw=black,fill=blue!15},
                lineArrow/.style={arrows={-Latex[length=5pt 3 0]}},
                every fit/.style={inner sep=.4em,draw}
            ]
                \node (browser) [block] {Webbrowser};
                \node (fitClient) [rounded corners,fit=(browser)] {};
                \node [left] at (fitClient.west) {Client};
            
                \onslide<4>{\node (JSF) [halfselected,below of=browser,node distance=5em] {Java Server Faces};}
                \onslide<1-3>{\node (JSF) [block,below of=browser,node distance=5em] {Java Server Faces};}
                \onslide<1>{\node (EJB) [selected,below of=JSF] {Enterprise Java Beans};}
                \onslide<2-4>{\node (EJB) [block,below of=JSF] {Enterprise Java Beans};}
                \onslide<2>{\node (JPA) [selected,below of=EJB] {Java Persistance API};}
                \onslide<1,3,4>{\node (JPA) [block,below of=EJB] {Java Persistance API};}
                \onslide<3>{\node (openJPA) [selected, below of=JPA] {OpenJPA Cache};}
                \onslide<1,2,4>{\node (openJPA) [block, below of=JPA] {OpenJPA Cache};}
                \node (fitGlassfish) [rounded corners,fit=(JSF) (EJB) (JPA) (openJPA)] {};
                \node [left] at (fitGlassfish.west) [text width=1.5cm] {GlassFish/ Payara};
    
                \node (memoryBuffers) [block, below of=openJPA] {Memory Buffers};
                \node (services) [block, right of=memoryBuffers, xshift=2cm] {Services};
                \onslide<4>{\node (database) [selected, below of=memoryBuffers] {Database};}
                \onslide<1-3>{\node (database) [block, below of=memoryBuffers] {Database};}
                \node (fitPostgreSQL) [rounded corners,fit=(memoryBuffers) (services) (database)] {};
                \node [left] at (fitPostgreSQL.west) {PostgreSQL};
    
                \node (fitServer) [rounded corners,fit=(fitGlassfish) (fitPostgreSQL),inner xsep=3em] {};
                \node [left] at (fitServer.west) {Server};
    
                \draw[lineArrow] (browser)--(JSF);
                \draw[lineArrow] (JSF)--(EJB);
                \draw[lineArrow] (EJB)--(JPA);
                \draw[lineArrow] (JPA)--(openJPA);
                \draw[lineArrow] (openJPA)--(memoryBuffers);
                \draw[lineArrow] (memoryBuffers)--(database);
                \draw[lineArrow] (services)|-(database);
            \end{tikzpicture}
            %\label{fig:webrequest}
        \end{figure}
    \end{columns}
\end{frame}

% 5. Methodik
\section{Methodik}
\begin{frame}[c]
    \frametitle{Voraussetzungen}
    \begin{itemize}
        \item Verwendung von Docker, zur Performance"=Limitierung
        \item Eigene Container für die Datenbank und den Webserver
        \item Für die Untersuchung wird lediglich die Dokumentenliste beobachtet
        \item Verwendung von Scripts zur besseren Vergleichbarkeit und Wiederholgenauigkeit
    \end{itemize}
\end{frame}

\begin{frame}[c]
    \frametitle{Vorgehen}
    \begin{itemize}
        \item Vor jeder Messung werden die Container neugestartet und die Startroutinen abgewartet
        \item Aufruf eines Bash"=Script auf dem gleichen Rechner wie die Docker-Container, um die Latenz des Netzwerkes auszuschließen
        \item Ermittlung des Speicherbedarfs vor und nach dem Aufrufen der Webseiten
        \item Messung der Aufruf der Index"=Seite (ohne Datenbankaufrufe) und der Dokumentenliste, jeweils 10 mal
        \item Report über die SQL"=Abfragen mit pgBadger erstellen
    \end{itemize}
\end{frame}

\begin{frame}[c]
    \frametitle{Erste Auffälligkeiten}
    \begin{itemize}
        \item OutOfMemory"=Ausnahme ausgelöst nach dem vierten Script Aufruf ($\sim$40 Webseitenaufrufe)
        \item Erhöhung des Java"=Heapspeichers von 512MB auf 4096MB hat nur die Anzahl der Aufrufe bis zum Absturz verzögert
    \end{itemize}
\end{frame}

\section{Untersuchungen}
\begin{frame}[c]
    \frametitle{Vergleichsmessung - Ohne Cache}
    \begin{columns}
        \column{0.5\textwidth}
        \begin{overprint}
            \begin{itemize}
                \item Deaktivieren aller Caches
                \item Auffälliger Speicheranstieg, trotz deaktiviertem Cache
                \item Gleichmässige Anzahl an Datenbankabfragen
                \item Gleichmässige Laufzeit der Datenbankabfragen
                \item Laufzeitanteil der Datenbankabfragen unter 10\%
            \end{itemize}
        \end{overprint}

        \column{0.5\textwidth}
        \centering
        \resizebox{0.8\textwidth}{!}{ \begin{tabular}{r|r|r|r|r|r}
            \thead{\#} & \thead{Call \\ (ms)} & \thead{Query \\ (\# / ms)} & \thead{Memory \\ Diff (MB)} & \thead{Render \\ (ms)} & \thead{DB"=load \\ (ms)} \\
            \hline
            \hline
            0 & 1931 &             - &     - & 1849 & 710 \\
            1 &  682 & 1223.0 / 30.3 &  54.8 &  666 & 399 \\
            2 &  389 & 1208.0 / 31.2 & 172.5 &  378 & 282 \\
            3 &  407 & 1208.0 / 33.5 & 110.0 &  398 & 307 \\
            4 &  359 & 1208.0 / 33.7 & 193.0 &  351 & 269 \\
            \textbf{5} &  317 & 1208.0 / 32.9 & 107.0 &  309 & 235 \\
        \end{tabular} }
  
        \vspace{10pt}
        \begin{tikzpicture}[scale=0.2,every node/.style={scale=0.6}]
            % Zeichne die Balken von unten nach oben
            \draw[fill=red] (0,0) rectangle (31.7,1.5);    % WebRequest
            \draw[fill=orange] (0,1.5) rectangle (30.9,3); % Render
            \draw[fill=yellow] (0,3) rectangle (23.5,4.5); % DB-Load
            \draw[fill=green] (0,4.5) rectangle (3.3,6);   % DB
            % Beschriftungen hinzufügen
            \node at (15.0, 0.7) {WebRequest};
            \node at (15.0, 2.2) {Render};
            \node at (15.0, 3.7) {DB"=Load};
            \node at (15.0, 5.2) {Queries};
        \end{tikzpicture}
  \end{columns}
\end{frame}

% Hier 2-3 der aktuellen erarbeiten Ansätze Vorstellen und nach dem Warum fragen
% Genau beschreiben was Signifikant besser/schlechter ist

\begin{frame}
    \frametitle{Caching EJB}

    \begin{itemize}
        \item Konfiguration über die Webseite des Payara"=Servers
        \item Hat keine Auswirkungen auf die Performance
        \item Der Cache wird nur von den Providern selbst und nicht den geladenen Datenbank"=Objekten verwendet
    \end{itemize}
    
    \vspace{8pt}
    \begin{corollary}
        Nicht nutzbar für dieses Szenario
    \end{corollary}
\end{frame}

\begin{frame}
    \frametitle{Abfragesprachen}

    \begin{itemize}
        \item Ähnliche gemessene Zeiten
        \item Untersuchung im Debugger zeigt ähnlichen Abfrage"=Syntax innerhalb von OpenJPA
        \item Prüfung der SQL"=Abfragen zeigt, dass die identischen Befehle an die Datenbank übertragen werden
        \item Kein Unterschied im Speicherverbrauch feststellbar
        \item Gleiche Optimierung durch Hint \texttt{openjpa.FetchPlan.EagerFetchMode} (halbierte Laufzeit, geviertelte Datenbankaufrufe)
        \item Andere Hints hatten keine messbaren Auswirkungen
    \end{itemize}
    
    \vspace{8pt}
    \begin{corollary}
        Daher kann die Art der Programmierung verwendet werden, die für den Anwendungsfall die einfachere ist
    \end{corollary}
\end{frame}

%\subsection{OpenJPA-Cache}
\begin{frame}[c]
    \frametitle{Caching mit OpenJPA}
    \begin{columns}
        \begin{column}{0.5\textwidth}
        \begin{overprint}
            
        \onslide<1>
            \begin{itemize}
                \item Einfaches aktivieren
                \item Direkte Unterstützung
                \item Konfiguration über die Anzahl der Objekte
                \item Messung mit 1000 und 10000 Objekten
            \end{itemize}
        
        \onslide<2>
            \begin{itemize}
                \item Erwartete Reduzierung der Datenbankabfragen
                \item Laufzeit in der Datenbank halbiert sich nicht, trotz halbierter Abfragen 
                \item Speicheranstieg wurde reduziert
            \end{itemize}
        
        \end{overprint}
        \end{column}

        % Rechte Spalte
        \column{0.5\textwidth}
        \center
        \resizebox{0.8\textwidth}{!}{\begin{tabular}{r|r|r|r|r|r}
            \thead{\#} & \thead{Call \\ (ms)} & \thead{Query \\ (\# / ms)} & \thead{Memory \\ Diff (MB)} & \thead{Render \\ (ms)} & \thead{DB"=load \\ (ms)} \\
            \hline
            \hline
            ref-5 &  317 & 1208.0 / 32.9 & 107.0 &  309 & 235 \\
            \hline
            \hline
            0 & 2347 &             - &     - & 2286 & 770 \\
            1 &  611 &  730.2 / 28.8 &  39.2 &  595 & 284 \\
            %2 &  319 &  667.3 / 25.8 & 117.3 &  309 & 195 \\
            3 &  281 &  680.6 / 27.6 &  56.0 &  271 & 180 \\
            %4 &  280 &  671.3 / 27.6 &  55.0 &  271 & 189 \\
            5 &  272 &  683.6 / 27.6 &  97.0 &  264 & 175 \\
            \hline
            \hline
            0 & 1904 &             - &     - & 2232 & 847 \\
            1 &  368 &  141.2 / 20.8 &  30.5 &  404 & 124 \\
            %2 &  143 &    6.0 / 20.5 &   3.6 &  136 &  36 \\
            3 &  126 &    6.0 / 19.9 &   3.3 &  136 &  47 \\
            %4 &  124 &    6.0 / 21.4 &   1.1 &  113 &  39 \\
            \textbf{5} &  114 &    6.0 / 19.7 &   1.2 &  107 &  32 \\
        \end{tabular} }

        \vspace{8pt}
        \begin{tikzpicture}[scale=0.2,every node/.style={scale=0.6}]
            % Zeichne die Balken von unten nach oben
            \draw[fill=red] (0,7) rectangle (31.7,8.5);      % WebRequest
            \draw[fill=orange] (0,8.5) rectangle (30.9,10);  % Render
            \draw[fill=yellow] (0,10) rectangle (23.5,11.5); % DB-Load
            \draw[fill=green] (0,11.5) rectangle (3.3,13);   % DB
            % Beschriftungen hinzufügen
            \node at (15.0, 7.7) {ref"=Call};
            \node at (15.0, 9.2) {ref"=Render};
            \node at (15.0, 10.7) {ref"=DB"=Load};
            \node at (15.0, 12.2) {ref"=Queries};

            % Zeichne die Balken von unten nach oben
            \draw[fill=red] (0,0) rectangle (11.4,1.5);    % WebRequest
            \draw[fill=orange] (0,1.5) rectangle (10.7,3); % Render
            \draw[fill=yellow] (0,3) rectangle (3.2,4.5);  % DB-Load
            \draw[fill=green] (0,4.5) rectangle (2.0,6);   % DB
            % Beschriftungen hinzufügen
            \node at (7.0, 0.7) {Call};
            \node at (7.0, 2.2) {Render};
            \node at (7.0, 3.7) {DB"=Load};
            \node at (7.0, 5.2) {Queries};
        \end{tikzpicture}
    \end{columns}
\end{frame}

\begin{frame}[c]
    \frametitle{Cached Queries}
    \begin{itemize}
        \item Einfaches aktivieren
        \item Einzelne Abfragen können ausgeschlossen werden
        \item Keine Auswirkung auf die Performance
        \item Wird nur beachtet wenn keine Argumente vorhanden sind
    \end{itemize}

    \vspace{8pt}
    \begin{corollary}
        Nur gut verwendbar, wenn keine Bedingungen vorhanden sind
    \end{corollary}
\end{frame}

\begin{frame}[c]
    \frametitle{Caching mit Ehcache}
    \begin{columns}
        \column{0.5\textwidth}
        \begin{overprint}
            \onslide<1>
            \begin{itemize}
                \item Benötigt zusätzliche Pakete
                \item Aufwendigere Konfiguration, ohne Fehlerausgabe
                \item Zusätzliche Konfiguration bzw. Code zum aktivieren des Caches
                \item Weitere Konfiguration an den Klassen möglich
            \end{itemize}

            \onslide<2>
            \begin{itemize}
                \item Erwartete Reduzierung der Datenbankabfragen
                \item Laufzeit der Datenbankabfragen halbiert sich nur, trotz signifikant weniger Abfragen
                \item Starke Reduzierung der Laderoutine von Datenbank nach Java"=Objekten
                \item Geringer Speicheranstieg trotz des Caches
                \item Sehr effizienter Cache, auch bei größeren Datenmengen
            \end{itemize}
        \end{overprint}
        
        \column{0.5\textwidth}
        \centering
        \resizebox{\textwidth}{!}{\begin{tabular}{r|r|r|r|r|r}
            \thead{\#} & \thead{Call \\ (ms)} & \thead{Query \\ (\# / ms)} & \thead{Memory \\ Diff (MB)} & \thead{Render \\ (ms)} & \thead{DB"=load \\ (ms)} \\
            \hline
            \hline
            ref-5 &  317 & 1208.0 / 32.9 & 107.0 &  309 & 235 \\
            \hline
            \hline
            0 & 2820 &              - &     - & 2809 & 1186 \\
            1 &  488 &   135.2 / 20.7 &  24.4 &  490 &  175 \\
            2 &  144 &     6.0 / 20.1 &   1.0 &  136 &   38 \\
            3 &  129 &     6.0 / 19.4 &   1.0 &  121 &   34 \\
            4 &  123 &     6.0 / 19.7 &   8.0 &  116 &   33 \\
            \textbf{5} &  118 &     6.0 / 12.7 &   4.0 &  111 &   34 \\
        \end{tabular} }

        \vspace{10pt}
        \begin{tikzpicture}[scale=0.2,every node/.style={scale=0.6}]
            % Zeichne die Balken von unten nach oben
            \draw[fill=red] (0,7) rectangle (31.7,8.5);      % WebRequest
            \draw[fill=orange] (0,8.5) rectangle (30.9,10);  % Render
            \draw[fill=yellow] (0,10) rectangle (23.5,11.5); % DB-Load
            \draw[fill=green] (0,11.5) rectangle (3.3,13);   % DB
            % Beschriftungen hinzufügen
            \node at (15.0, 7.7) {ref"=Call};
            \node at (15.0, 9.2) {ref"=Render};
            \node at (15.0, 10.7) {ref"=DB"=Load};
            \node at (15.0, 12.2) {ref"=Queries};

            % Zeichne die Balken von unten nach oben
            \draw[fill=red] (0,0) rectangle (11.8,1.5);    % WebRequest
            \draw[fill=orange] (0,1.5) rectangle (11.1,3); % Render
            \draw[fill=yellow] (0,3) rectangle (3.4,4.5);  % DB-Load
            \draw[fill=green] (0,4.5) rectangle (1.3,6);   % DB
            % Beschriftungen hinzufügen
            \node at (6.0, 0.7) {Call};
            \node at (6.0, 2.2) {Render};
            \node at (6.0, 3.7) {DB"=Load};
            \node at (6.0, 5.2) {Queries};
        \end{tikzpicture}
    \end{columns}
\end{frame}

%\subsection{Materialized View}
\begin{frame}[c]
    \frametitle{Abfragen über materialized views}
    \begin{columns}
        \column{0.5\textwidth}
        \begin{overprint}
            \onslide<1>
            \begin{itemize}
                \item Materialized View und Webseite aus dem aktuellen Wedekind"=Projekt übernommen \citep{Dokument53:online}
                \item Zusätzliche Anpassung an der View, um die Parameter in der Abfrage zu entfernen für Test mit QueryCache
                \item Verschiebung des JSON"=Parsen in den Webclient
            \end{itemize}
            
            \onslide<2>
            \begin{itemize}
                \item Deutliche Reduzierung der Datenbankabfragen und "=laufzeiten
                \item Unter"=Abfragen werden als JSON"=Objekte direkt hinterlegt
                \item Teuer beim Erstellen, aber selten notwendig
                \item Geringe Schwankung der Aufrufzeiten
                \item Anteil der Datenbank nochmals reduziert
                \item Deutliche Reduzierung der DB"=Load Laufzeit durch Verschiebung des JSON"=Parsing
            \end{itemize}
        \end{overprint}

        \column{0.5\textwidth}
        \centering
        \resizebox{\textwidth}{!}{\begin{tabular}{r|r|r|r|r|r}
            \thead{\#} & \thead{Call \\ (ms)} & \thead{Query \\ (\# / ms)} & \thead{Memory \\ Diff (MB)} & \thead{Render \\ (ms)} & \thead{DB"=load \\ (ms)} \\
            \hline
            \hline
            ref-5 &  317 & 1208.0 / 32.9 & 107.0 &  309 & 235 \\
            \hline
            \hline
            0  &  859 &          - &     - &  803 & 334 \\
            1  &  348 & 16.8 / 2.5 &  36.4 &  331 & 174 \\
            2  &  194 &  9.0 / 2.4 &   2.6 &  185 &  99 \\
            3  &  161 &  9.0 / 2.4 &   3.0 &  152 &  77 \\
            4  &  145 &  9.0 / 2.4 &  -3.4 &  137 &  73 \\
            5  &  137 &  9.0 / 2.4 &   3.0 &  129 &  72 \\
            \textbf{js} & 70+13 &    9.0 / 2.4 &     - & $\sim$60 &   4 \\
        \end{tabular} }

        \vspace{8pt}
        \begin{tikzpicture}[scale=0.2,every node/.style={scale=0.6}]
            % Zeichne die Balken von unten nach oben
            \draw[fill=red] (0,7) rectangle (31.7,8.5);      % WebRequest
            \draw[fill=orange] (0,8.5) rectangle (30.9,10);  % Render
            \draw[fill=yellow] (0,10) rectangle (23.5,11.5); % DB-Load
            \draw[fill=green] (0,11.5) rectangle (3.3,13);   % DB
            % Beschriftungen hinzufügen
            \node at (15.0, 7.7) {ref"=Call};
            \node at (15.0, 9.2) {ref"=Render};
            \node at (15.0, 10.7) {ref"=DB"=Load};
            \node at (15.0, 12.2) {ref"=Queries};
            
            % Zeichne die Balken von unten nach oben (9)
            \draw[fill=red] (0,0) rectangle (8.3,1.5);    % WebRequest
            \draw[fill=orange] (0,1.5) rectangle (6,3);   % Render
            \draw[fill=yellow] (0,3) rectangle (0.4,4.5); % DB-Load
            \draw[fill=green] (0,4.5) rectangle (0.3,6);  % DB
            % Zeichne die Balken von unten nach oben (5)
            %\draw[fill=red] (0,0) rectangle (13.7,1.5);    % WebRequest
            %\draw[fill=orange] (0,1.5) rectangle (12.9,3); % Render
            %\draw[fill=yellow] (0,3) rectangle (7.2,4.5);  % DB-Load
            %\draw[fill=green] (0,4.5) rectangle (0.3,6);   % DB
            % Beschriftungen hinzufügen
            \node at (3.0, 0.7) {Complete};
            \node at (3.0, 2.2) {Server"=Side};
            \node at (3.0, 3.7) {DB"=Load};
            \node at (3.0, 5.2) {Queries};
        \end{tikzpicture}
    \end{columns}
\end{frame}

\begin{frame}[c]
    \frametitle{Optimierung der Abfrage}
    \begin{columns}
        \column{0.5\textwidth}
        \begin{overprint}
            \onslide<1>
            \begin{itemize}
                \item Große Datenmenge vom ersten Befehl bis fast zur Ausgabe
                \item Höchste Kosten im Seq Scan der Dokumententabelle
                \item Nur Seq Scan bei den verlinkten Tabellen
                \item Am Ende ist ein teurer Sort notwendig
            \end{itemize}

            \onslide<2>
            \begin{itemize}
                \item Umstellung mit dem WITH"=Statement
                \item Große Datenmenge verschwindet nach dem ersten Hash join
                \item Verwendung von Index Scan
                \item Reduktion der Kosten der Sortierung am Ende
                \item Reduktion der Laufzeit um den Faktor drei
                \item Nur möglich, wenn die Bedingungen ins WITH eingetragen werden können
            \end{itemize}
        \end{overprint}

        \column{0.5\textwidth}
        \begin{overprint}
            \onslide<1>
            \includegraphics[width=\textwidth]{gfx/chapter05_ExplainVisualize.png}
            
            \onslide<2>
            \includegraphics[width=\textwidth]{gfx/chapter05_ExplainVisualize_with.png}
        \end{overprint}
    \end{columns}
\end{frame}

\section{Fazit}
\begin{frame}[c]
    \frametitle{Vergleich}
    \begin{columns}
    \column{0.5\textwidth}
        \centering
        \begin{tikzpicture}[scale=.4]
        \begin{axis}[
            title={Laufzeitvergleich Webseitenaufrufe},
            ymax=1200,
        ]
            \addplot coordinates {(0,1931) (1,682)(2,389)(3,407)(4,359)(5,317)};
            \addplot coordinates {(0,2347) (1,611)(2,319)(3,281)(4,280)(5,272)};
            \addplot coordinates {(0,1904) (1,368)(2,143)(3,126)(4,124)(5,114)};
            \addplot coordinates {(0,2820) (1,488)(2,144)(3,129)(4,123)(5,118)};
            \addplot coordinates {(0, 859) (1,348)(2,194)(3,161)(4,145)(5,137)};
            \addplot coordinates {(5,  83)};
            \legend{Ohne Cache,OpenJPA Cache,OpenJPA Cache groß,Ehcache,Materialized View,Materialized View JS}
        \end{axis}
        \end{tikzpicture}

        \centering
        \begin{tikzpicture}[scale=.4]
        \begin{axis}[
            title={Laufzeitvergleich Datenbankabfragen},
            ymax=80,
            xtick={1,2,3,4,5}, %Ticks explizit angeben, dass bei grpßerer Darstellung nicht Zwischenticks existieren
        ]
            \addplot coordinates {(1,30.3)(2,31.5)(3,33.5)(4,33.7)(5,32.9)};
            \addplot coordinates {(1,28.8)(2,25.8)(3,27.6)(4,27.6)(5,27.6)};
            \addplot coordinates {(1,20.8)(2,20.5)(3,19.9)(4,21.4)(5,19.7)};
            \addplot coordinates {(1,20.7)(2,20.1)(3,19.4)(4,19.7)(5,12.7)};
            \addplot coordinates {(1, 2.5)(2, 2.4)(3, 2.4)(4, 2.4)(5, 2.4)};
            \addplot coordinates {(5, 2.4)};
            \legend{Ohne Cache,OpenJPA Cache,OpenJPA Cache groß,Ehcache,Materialized View,Materialized View JS}
        \end{axis}
        \end{tikzpicture}

    \column{0.5\textwidth}
        \centering
        \begin{tikzpicture}[scale=.4]
        \begin{axis}[
            title={Laufzeitvergleich Render},
            ymax=1200,
        ]
            \addplot coordinates {(0,1849) (1,666)(2,378)(3,398)(4,351)(5,309)};
            \addplot coordinates {(0,2286) (1,595)(2,309)(3,271)(4,271)(5,264)};
            \addplot coordinates {(0,2232) (1,404)(2,136)(3,136)(4,113)(5,107)};
            \addplot coordinates {(0,2809) (1,490)(2,136)(3,121)(4,116)(5,111)};
            \addplot coordinates {(0, 803) (1,331)(2,185)(3,152)(4,137)(5,129)};
            \addplot coordinates {(5,  60)};
            \legend{Ohne Cache,OpenJPA Cache,OpenJPA Cache groß,Ehcache,Materialized View,Materialized View JS}
        \end{axis}
        \end{tikzpicture}

        \centering
        \begin{tikzpicture}[scale=.4]
        \begin{axis}[
            title={Laufzeitvergleich DB"=Load},
            ymax=1200,
        ]
            \addplot coordinates {(0, 710) (1,399)(2,282)(3,307)(4,269)(5,235)};
            \addplot coordinates {(0, 770) (1,284)(2,195)(3,180)(4,189)(5,175)};
            \addplot coordinates {(0, 847) (1,124)(2, 36)(3, 47)(4, 39)(5, 32)};
            \addplot coordinates {(0,1186) (1,175)(2, 38)(3, 34)(4, 33)(5, 34)};
            \addplot coordinates {(0, 334) (1,174)(2, 99)(3, 77)(4, 73)(5, 72)};
            \addplot coordinates {(5,   4)};
            \legend{Ohne Cache,OpenJPA Cache,OpenJPA Cache groß,Ehcache,Materialized View,Materialized View JS}
        \end{axis}
        \end{tikzpicture}
    \end{columns}
\end{frame}

\begin{frame}
    \frametitle{Vergleich der besten Laufzeiten}
    \begin{columns}
        \column{0.5\textwidth}
        \begin{tikzpicture}[scale=0.2,every node/.style={scale=0.6}]
            % Zeichne die Balken von unten nach oben
            \draw[fill=red] (0,26) rectangle (31.7,27.5);    % WebRequest
            \draw[fill=orange] (0,27.5) rectangle (30.9,29); % Render
            \draw[fill=yellow] (0,29) rectangle (23.5,30.5); % DB-Load
            \draw[fill=green] (0,30.5) rectangle (3.3,32);   % DB
            % Beschriftungen hinzufügen
            \node at (9.0, 26.7) {ref"=Call};
            \node at (9.0, 28.2) {ref"=Render};
            \node at (9.0, 29.7) {ref"=DB"=Load};
            \node at (9.0, 31.2) {ref"=Queries};
            %\node at (25.0, 28.8) {ohne Cache};

            % OpenJPA
            % Zeichne die Balken von unten nach oben
            \draw[fill=red] (0,19.5) rectangle (11.4,21);    % WebRequest
            \draw[fill=orange] (0,21) rectangle (10.7,22.5); % Render
            \draw[fill=yellow] (0,22.5) rectangle (3.2,24);  % DB-Load
            \draw[fill=green] (0,24) rectangle (2.0,25.5);   % DB
            % Beschriftungen hinzufügen
            \node at (6.0, 20.2) {Call};
            \node at (6.0, 21.7) {Render};
            \node at (6.0, 23.2) {DB"=Load};
            \node at (6.0, 24.7) {Queries};
            \node at (25.0, 22.6) {OpenJPA 10000 Objekte};
            
            % Ehcache
            % Zeichne die Balken von unten nach oben
            \draw[fill=red] (0,13) rectangle (11.8,14.5);    % WebRequest
            \draw[fill=orange] (0,14.5) rectangle (11.1,16); % Render
            \draw[fill=yellow] (0,16) rectangle (3.4,17.5);  % DB-Load
            \draw[fill=green] (0,17.5) rectangle (1.3,19);   % DB
            % Beschriftungen hinzufügen
            \node at (6.0, 13.7) {Call};
            \node at (6.0, 15.2) {Render};
            \node at (6.0, 16.7) {DB"=Load};
            \node at (6.0, 18.2) {Queries};
            \node at (25.0, 15.8) {Ehcache};
            
            % matview normal
            % Zeichne die Balken von unten nach oben (5)
            \draw[fill=red] (0,6.5) rectangle (13.7,8);    % WebRequest
            \draw[fill=orange] (0,8) rectangle (12.9,9.5); % Render
            \draw[fill=yellow] (0,9.5) rectangle (7.2,11); % DB-Load
            \draw[fill=green] (0,11) rectangle (0.3,12.5); % DB
            \node at (3.0,  7.2) {Call};
            \node at (3.0,  8.7) {Render};
            \node at (3.0, 10.2) {DB"=Load};
            \node at (3.0, 11.7) {Queries};
            \node at (25.0, 9.3) {Materialized View};
 
            % matview parseJson Client
            % Zeichne die Balken von unten nach oben (9)
            \draw[fill=red] (0,0) rectangle (8.3,1.5);    % WebRequest
            \draw[fill=orange] (0,1.5) rectangle (6,3);   % Render
            \draw[fill=yellow] (0,3) rectangle (0.4,4.5); % DB-Load
            \draw[fill=green] (0,4.5) rectangle (0.3,6);  % DB
            % Beschriftungen hinzufügen
            \node at (3.0, 0.7) {Complete};
            \node at (3.0, 2.2) {Server"=Side};
            %\node at (3.0, 0.7) {Call};
            %\node at (3.0, 2.2) {Render};
            \node at (3.0, 3.7) {DB"=Load};
            \node at (3.0, 5.2) {Queries};
            \node at (25.0, 2.8) {Materialized View Client"=Parsing};
        \end{tikzpicture}
        
        \column{0.5\textwidth}
        \begin{itemize}
            \item Die Datenbankabfragen nehmen den kleinsten Teil der Laufzeit ein
            \item Beim Großteil der Optimierung wird die Zeit bei DB"=Load verringert
            \item Die Differenz zwischen DB"=Load und Render verändert sich gering
            \item Hoher Offset im DB"=Load, außer bei Materialized View mit Client Parsing
            \item Materialized View geringste Datenbankabfragezeiten, aber nicht schneller als OpenJPA-Cache mit größerem Cache
            %\item Die erhöhte Differenz bei zwischen Render und Call bei Materialized View mit Client Parsing ist der Client"=Anteil
        \end{itemize}
    \end{columns}
 \end{frame}

\begin{frame}
    \frametitle{Zusammenfassung}

    \begin{itemize}
        \item Query"=Cache und EJB"=Cache nicht verwendbar
        \item Bei Verwendung von Cache auf Ehcache umstellen, OpenJPA"=Cache ist ineffizienter
        \item Die Wahl der Abfragesprache hat keine Performance"=Beeinflussung
        \item Verwendung der Materialized"=View mit JSON"=Parsing am Client hat die beste Performance
        \item Abfragen können optimiert werden, aber besitzen nur geringe Auswirkung auf den gesamten Aufruf
        \item Größtes Optimierungspotential im ORM vorhanden, bei der Bereitstellung der Entitäten (gut an der Umsetzung mit Materialized"=View zu sehen)
    \end{itemize}

\end{frame}

\begin{frame}
    \frametitle{Ausblick}

    \begin{itemize}
        \item Weitestgehende optimale Umsetzung der Schichten im GlassFish"=Server, bzw. wenige Optimierungsmöglichkeiten
        \item Verlagerung des Aufbaus der Darstellung an den Client um weniger Ressourcen am Server zu nutzen
        \item Speicherleck im OpenJPA durch neue Version behebbar
        \item Wechseln auf anderen ORM oder eigene Entwicklung
        \item Verwendung von Caches benötigen zusätzliche Ressourcen, daher nicht sinnvoll bei schwächeren Serversystemen
    \end{itemize}
\end{frame}

% -- SLIDE -- REFERENCES
% hier alle Keys aus der BIB einfügen, die mit dargestellt werden sollen
\nocite{IbmOpenJPACaching2023,PostgresPro:Chap20.4:2023}
%% Für mehreren Seite bei den Referenzen ein ",allowframebreaks" in den [] hinzufügen
\begin{frame}[t]
    \frametitle{Referenzen}
    \printbibliography[title=Referenzen]
\end{frame}

\end{document}