Queer European MD passionate about IT
Parcourir la source

Finished working on first assignment

Davte il y a 4 ans
Parent
commit
2542824aae
2 fichiers modifiés avec 194 ajouts et 18 suppressions
  1. 13 2
      compitino/main.tex
  2. 181 16
      compitino/primo_compitino/piani_di_accesso.tex

+ 13 - 2
compitino/main.tex

@@ -8,7 +8,16 @@
 \usepackage{listings}
 \usepackage{pxfonts}
 \usepackage{textcomp}
+\usepackage[normalem]{ulem}
+\usepackage{geometry}
 
+\geometry{
+a4paper,
+top=30mm,
+}
+
+\forestset{qtree/.style={for tree={parent anchor=south,
+           child anchor=north,align=center,inner sep=0pt}}}
 \lstset{upquote=true,showstringspaces=false}
 \lstdefinestyle{SQLu}{
     language=SQL,
@@ -27,7 +36,7 @@
 % First page information
 \title{\textbf{Basi di dati prof. Ghelli}\linebreak\textit{``Sempre sul pezzo"}}
 \author{Davide Testa 613565}
-\date{2020-05-??}
+\date{2020-05-15}
 
 \begin{document}
     \maketitle % Insert the title, author and date
@@ -36,7 +45,7 @@
     \section{Descrizione del dominio}\label{sec:dominio}
         \input{\folder/dominio.tex}
     \section{Schema concettuale}\label{sec:schema-concettuale}
-        \begin{figure}[htb]
+        \begin{figure}[hb]
           \centering
           \includegraphics[width=\linewidth]{\folder/schema_concettuale.pdf}
           \caption{Schema concettuale in formato grafico}
@@ -51,8 +60,10 @@
           \label{fig:schema-logico}
         \end{figure}
         \input{\folder/schema_logico.tex}
+    \clearpage
     \section{Interrogazioni}\label{sec:queries}
         \input{\folder/queries.tex}
+    \vskip2pc
     \section{Piani di accesso}\label{sec:piani}
         \input{\folder/piani_di_accesso.tex}
 \end{document}

+ 181 - 16
compitino/primo_compitino/piani_di_accesso.tex

@@ -1,25 +1,190 @@
 % !TEX root = ../main.tex
+\subsection{Query a}
 
-%π e.Titolo, sw.Url
-%|
-%⋈ e.IdEdizione = sw.IdEdizione
+\paragraph{Piano di accesso logico della query a}
+\begin{center}
+  \begin{forest}
+      [{$\pi^{b}$ e.Titolo, sw.Url}
+          [{$\bowtie$ e.IdEdizione = sw.IdEdizione}
+              [{$\sigma$e.Titolo $>=$'G' $\wedge$ e.Titolo $<$ 'H'}
+                  [Edizioni e]
+              ]
+              [SitiWeb sw]
+          ]
+      ]
+  \end{forest}
+\end{center}
 
-%σ  e.Titolo<‘H’
-%
-%|
-%Edizioni e
+\paragraph{Piano di accesso fisico della query a senza indici}
+\begin{center}
+  \begin{forest}
+      [{Project(\{e.Titolo, sw.Url\})}
+          [{SortMerge(e.IdEdizione = sw.IdEdizione)}
+              [{Sort(\{e.IdEdizione\})}
+                  [{Project(\{e.Titolo, e.IdEdizione\})}
+                    [{Filter(e.Titolo $>=$ 'G' AND e.Titolo $<$ H)}
+                      [{TableScan(Edizioni e)}]
+                    ]
+                  ]
+              ]
+              [{Sort(\{sw.IdEdizione\})}
+                [{Project(\{sw.Url, sw.IdEdizione\})}
+                  [{TableScan(SitiWeb sw)}]
+                ]
+              ]
+          ]
+      ]
+  \end{forest}
+\end{center}
 
+\paragraph{Piano di accesso fisico della query a con due indici}
+\begin{center}
+  \begin{forest}, baseline, qtree
+      [{Project(\{e.Titolo, sw.Url\})}
+          [{IndexNestedLoop(e.IdEdizione = sw.IdEdizione)}
+              [{IndexFilter(Edizioni e, IndETit,\\ e.Titolo $>=$ 'G' AND e.Titolo $<$ H)}]
+              [{IndexFilter(SitiWeb sw, IndSWIdEd,\\ e.IdEdizione = sw.IdEdizione)}]
+          ]
+      ]
+  \end{forest}
+\end{center}
+Indici necessari: \texttt{IndETit} (indice della tabella Edizioni sull’attributo Titolo) e \texttt{IndSWIdEd} (indice della tabella SitiWeb sulla chiave IdEdizione).
 
-%\paragraph{Piano di accesso logico della query a}
+\subsection{Query b}
+\paragraph{Piano di accesso logico della query b}
+\begin{center}
+  \begin{forest}
+      [{$\tau$(\{$-$TempoTotaleLettura\})}
+          [{$\pi^{b}$ v.IdUtente, SUM(v.TempoLettura) TempoTotaleLettura}
+            [{$\sigma$ SUM(v.TempoLettura) $>$ 10}
+              [{\{v.IdUtente\} $\gamma$ \{SUM(v.TempoLettura)\}}
+                [{$\sigma$ v.TempoLettura $<$ 60}
+                  [{Visite v}]
+                ]
+              ]
+            ]
+          ]
+      ]
+  \end{forest}
+\end{center}
+L’output dell’operatore $\gamma$ è già proiettato sulle sole dimensioni di analisi e risultati delle
+funzioni di aggregazione, non occorrerebbe proiettare su \texttt{\{v.IdUtente, SUM(v.TempoLettura)\}}; lo faccio per poter rinominare in TempoTotaleLettura il risultato della SUM.
+
+Nella $\tau$, l’ordinamento discendente è reso dal segno `$-$' per convenzione (in questo caso comunque il tipo è numerico).
+
+\paragraph{Piano di accesso fisico della query b senza indici}
+\begin{center}
+  \begin{forest}
+      [{Sort(\{$-$TempoTotaleLettura\})}
+        [{Project(\{v.IdUtente, SUM(v.TempoLettura) TempoTotaleLettura\})}
+          [{Filter(SUM(v.TempoLettura) $>$ 10)}
+            [{GroupBy(\{v.IdUtente\}, \{SUM(v.TempoLettura)\})}
+              [{Sort(\{v.IdUtente\})}
+                [{Project(\{v.IdUtente, v.TempoLettura\})}
+                  [{Filter(v.TempoLettura $<$ 60)}
+                    [{TableScan(Visite v)}]
+                  ]
+                ]
+              ]
+            ]
+          ]
+        ]
+      ]
+  \end{forest}
+\end{center}
+
+\clearpage
+\paragraph{Piano di accesso fisico della query b con indici}
+\begin{center}
+  \begin{forest}, baseline, qtree
+    [{Sort(\{$-$TempoTotaleLettura\})}
+      [{Project(\{v.IdUtente, SUM(v.TempoLettura) TempoTotaleLettura\})}
+        [{GroupBy(\{v.IdUtente\}, \{SUM(v.TempoLettura)\})}
+            [{\sout{Project(\{v.IdUtente, v.TempoLettura\})}}
+                [{IndexFilter(Visite v, IndVIdUt, v.TempoLettura $<$ 60)}
+                ]
+              ]
+            ]
+          ]
+        ]
+      ]
+    ]
+  \end{forest}
+\end{center}
+Indice necessario: \texttt{IndVIdUt} (indice della tabella Visite sull’attributo IdUtente).
+
+Non occorre ordinare prima di raggruppare: l’output di IndexFilter è già ordinato sull’insieme di attributi dell’indice (in questo caso \texttt{\{v.IdUtente\}}), che coincide nel nostro caso con l’insieme delle dimensioni di analisi.
+
+Non occorre nemmeno proiettare su \texttt{\{v.IdUtente, v.TempoLettura\}} prima del raggruppamento, in quanto la groupby può ricevere il record direttamente dalla IndexFilter e scartare gli attributi non rilevanti (cioè quelli che non sono dimensione di analisi né input delle funzioni di aggregazione).
+\subsection{Query c}
+\paragraph{Piano di accesso logico della query c}
+\begin{center}
+  \begin{forest}, baseline, qtree
+    [{$\pi$ a.IdArticolo, a.Titolo, COUNT(*) NumeroVisite,\\SUM(v.TempoLettura) TempoTotaleLettura}
+      [{$\sigma$ COUNT(*) $>=$ 3}
+        [{\{a.IdArticolo, a.Titolo\} $\gamma$ \{COUNT(*), SUM(v.TempoLettura)\}}
+          [{$\bowtie$ a.IdArticolo = v.IdArticolo}
+            [{$\sigma$ a.Premium = 'N'}
+              [{Articoli a}]
+            ]
+            [{Visite v}]
+          ]
+        ]
+      ]
+    ]
+  \end{forest}
+\end{center}
+\clearpage
+\paragraph{Piano di accesso fisico della query c senza indici}
+\begin{center}
+  \begin{forest}, baseline, qtree
+    [{Project(\{a.IdArticolo, a.Titolo, COUNT(*) NumeroVisite,\\SUM(v.TempoLettura) TempoTotaleLettura\})}
+      [{Filter(COUNT(*) $>=$ 3)}
+        [{GroupBy(\{a.IdArticolo, a.Titolo\}, \{COUNT(*), SUM(v.TempoLettura)\})}
+          [{SortMerge(a.IdArticolo = v.IdArticolo)}
+            [{Sort(a.IdArticolo)}
+              [{Project(\{a.IdArticolo, a.Titolo\})}
+                [{Filter(a.Premium = 'N')}
+                  [{TableScan(Articoli a)}]
+                ]
+              ]
+            ]
+            [{Sort(v.IdArticolo)}
+              [{Project(\{v.IdArticolo, v.TempoLettura\})}
+                [{TableScan(Visite v)}]
+              ]
+            ]
+          ]
+        ]
+      ]
+    ]
+  \end{forest}
+\end{center}
+L’output di SortMerge è già ordinato per a.IdArticolo e, dato che \texttt{a.IdArticolo $\to$ a.Titolo},
+non occorre ordinare prima della groupby.
 
-\begin{forest}
-\caption{Piano di accesso logico della query a}
-    [{$\pi^{b}_{e.Titolo, sw.Url}$}
-        [$\bowtie_{e.IdEdizione = sw.IdEdizione}$
-            [$\sigma_{e.Titolo>='G' \wedge e.Titolo<'H'}$
-                [Edizioni e]
+\paragraph{Piano di accesso fisico della query c con due indici}
+\begin{center}
+  \begin{forest}, baseline, qtree
+    [{Project(\{a.IdArticolo, a.Titolo, COUNT(*) NumeroVisite,\\SUM(v.TempoLettura) TempoTotaleLettura\})}
+      [{Filter(COUNT(*) $>=$ 3)}
+        [{GroupBy(\{a.IdArticolo, a.Titolo\}, \{COUNT(*), SUM(v.TempoLettura)\})}
+          [{IndexNestedLoop(a.IdArticolo = v.IdArticolo)}
+            [{Project(\{a.IdArticolo, a.Titolo\})}
+              [{IndexFilter(Articoli a,\\ IndAIdA, a.Premium = 'N')}
+              ]
             ]
-            [SitiWeb sw]
+            [{Project(\{v.IdArticolo, v.TempoLettura\})}
+                [{IndexFilter(Visite v,\\IndVIdA, v.IdArticolo = a.IdArticolo)}]
+              ]
+          ]
         ]
+      ]
     ]
-\end{forest}
+  \end{forest}
+\end{center}
+Indici necessari: IndAIdA (indice della tabella Articoli sull’attributo IdArticolo), IndVIdA (indice
+della tabella Visite sull’attributo IdArticolo).
+Non occorre fare un ordinamento sull’output della IndexNestedLoop: avendo ricevuto input
+ordinato su IdArticolo dalla IndexFilter, e sapendo che \texttt{a.IdArticolo $\to$ a.Titolo}, l’input
+della groupby è già raggruppato per le dimensioni di analisi.