123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- % !TEX root = ../main.tex
- \subsection{Query a}
- \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}
- \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).
- \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).
- \vfill
- \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.
- \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')}
- ]
- ]
- [{Project(\{v.IdArticolo, v.TempoLettura\})}
- [{IndexFilter(Visite v,\\IndVIdA, v.IdArticolo = a.IdArticolo)}]
- ]
- ]
- ]
- ]
- ]
- \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.
|