|
@@ -3,33 +3,35 @@
|
|
|
|
|
|
\paragraph{Piano di accesso logico della query a}
|
|
|
\begin{center}
|
|
|
- \begin{forest}
|
|
|
- [{$\pi^{b}$ R.C, S.D}
|
|
|
- [{$\bowtie$ R.E = S.F}
|
|
|
- [{$\sigma$ C $>=$ 10}
|
|
|
- [Tabella1 R]
|
|
|
+ \begin{forest}, baseline, qtree
|
|
|
+ [{$\pi^{b}$ r.IdRicetta , r.Nome}
|
|
|
+ [{$\bowtie$ p.IdPersona = r.IdCreatrice}
|
|
|
+ [{$\sigma$ p.Nome = 'Giovanni'}
|
|
|
+ [Persone p]
|
|
|
]
|
|
|
- [Tabella2 S]
|
|
|
+ [Ricette r]
|
|
|
]
|
|
|
]
|
|
|
\end{forest}
|
|
|
\end{center}
|
|
|
|
|
|
+Non c'è in questo caso differenza tra $\pi^{b}$ e $\pi$: non ci possono essere
|
|
|
+duplicati.
|
|
|
\paragraph{Piano di accesso fisico della query a senza indici}
|
|
|
\begin{center}
|
|
|
- \begin{forest}
|
|
|
- [{Project(\{C, D\})}
|
|
|
- [{SortMerge(R.E = S.F)}
|
|
|
- [{Sort(\{E\})}
|
|
|
- [{Project(\{E, C\})}
|
|
|
- [{Filter(C $>=$ 10)}
|
|
|
- [{TableScan(Tabella R)}]
|
|
|
+ \begin{forest}, baseline, qtree
|
|
|
+ [{Project(\{r.IdRicetta , r.Nome\})}
|
|
|
+ [{SortMerge(p.IdPersona = r.IdCreatrice)}
|
|
|
+ [{Sort([p.IdPersona])}
|
|
|
+ [{Project(\{p.IdPersona\})}
|
|
|
+ [{Filter(p.Nome = 'Giovanni')}
|
|
|
+ [{TableScan(Persone p)}]
|
|
|
]
|
|
|
]
|
|
|
]
|
|
|
- [{Sort(\{F\})}
|
|
|
- [{Project(\{C, F\})}
|
|
|
- [{TableScan(Tabella S)}]
|
|
|
+ [{Sort([r.IdCreatrice])}
|
|
|
+ [{Project(\{r.IdRicetta, r.Nome, r.IdCreatrice\})}
|
|
|
+ [{TableScan(Ricette r)}]
|
|
|
]
|
|
|
]
|
|
|
]
|
|
@@ -40,12 +42,179 @@
|
|
|
\paragraph{Piano di accesso fisico della query a con due indici}
|
|
|
\begin{center}
|
|
|
\begin{forest}, baseline, qtree
|
|
|
- [{Project(\{C, D\})}
|
|
|
- [{IndexNestedLoop(R.E = S.F)}
|
|
|
- [{IndexFilter(Tabella R,\\ IndRC, C $>=$ 10)}]
|
|
|
- [{IndexFilter(Tabella S,\\IndSF, S.F = R.E)}]
|
|
|
+ [{Project(\{r.IdRicetta , r.Nome\})}
|
|
|
+ [{IndexNestedLoop(p.IdPersona = r.IdCreatrice)}
|
|
|
+ [{IndexFilter(Persone p,\\ IndPN, p.Nome = 'Giovanni')}]
|
|
|
+ [{IndexFilter(Ricette r,\\IndRC, r.IdCreatrice = p.IdPersona)}]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ \end{forest}
|
|
|
+\end{center}
|
|
|
+Indici necessari: \texttt{IndPN} (indice della tabella Persone sull’attributo
|
|
|
+Nome) e \texttt{IndRC} (indice della tabella Ricette sull'attributo Creatrice).
|
|
|
+
|
|
|
+\clearpage
|
|
|
+\subsection{Query b}
|
|
|
+
|
|
|
+\paragraph{Piano di accesso logico della query b}
|
|
|
+\begin{center}
|
|
|
+ \begin{forest}, baseline, qtree
|
|
|
+ [{$\tau$[-DiversiFornitori]}
|
|
|
+ [{$\pi^{b}$ fa.IdBirrificio, COUNT(DISTINCT fa.IdFornitore) DiversiFornitori}
|
|
|
+ [{$\sigma$ COUNT(DISTINCT fa.IdFornitore) $>=$ 3}
|
|
|
+ [\{fa.IdBirrificio\} {$\gamma$ \{COUNT(DISTINCT fa.IdFornitore)\}}
|
|
|
+ [{$\sigma$ fa.Data $>=$ '2020-01-01'}
|
|
|
+ [Fatture fa]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ \end{forest}
|
|
|
+\end{center}
|
|
|
+
|
|
|
+Non c'è in questo caso differenza tra $\pi^{b}$ e $\pi$: non ci possono essere
|
|
|
+duplicati, in quanto la GROUP BY raggruppa per IdBirrificio.
|
|
|
+\paragraph{Piano di accesso fisico della query b senza indici}
|
|
|
+\begin{center}
|
|
|
+ \begin{forest}, baseline, qtree
|
|
|
+ [{Sort[-DiversiFornitori]}
|
|
|
+ [{Project(\{fa.IdBirrificio, COUNT(DISTINCT fa.IdFornitore) DiversiFornitori\})}
|
|
|
+ [{Filter(COUNT(DISTINCT fa.IdFornitore) $>=$ 3)}
|
|
|
+ [{GroupBy(\{fa.IdBirrificio\}, \{COUNT(DISTINCT fa.IdFornitore)\})}
|
|
|
+ [{Sort([fa.IdBirrificio])}
|
|
|
+ [{Filter(fa.Data $>=$ '2020-01-01')}
|
|
|
+ [{TableScan(Fatture fa)}]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ \end{forest}
|
|
|
+\end{center}
|
|
|
+Il sort sull'attributo dimensione di analisi prima della GroupBy è necessario,
|
|
|
+in quanto non è garantito che i record della tabella Fatture siano raggruppati
|
|
|
+per IdBirrificio.
|
|
|
+Lo sarebbero se l'organizzazione primaria della tabella fosse sequenziale
|
|
|
+proprio su questo attributo, il che è estremamente poco probabile.
|
|
|
+\clearpage
|
|
|
+\paragraph{Piano di accesso fisico della query b con un indice}
|
|
|
+\begin{center}
|
|
|
+ \begin{forest}, baseline, qtree
|
|
|
+ [{Sort[-DiversiFornitori]}
|
|
|
+ [{Project(\{fa.IdBirrificio, COUNT(DISTINCT fa.IdFornitore) DiversiFornitori\})}
|
|
|
+ [{Filter(COUNT(DISTINCT fa.IdFornitore) $>=$ 3)}
|
|
|
+ [{GroupBy(\{fa.IdBirrificio\}, \{COUNT(DISTINCT fa.IdFornitore)\})}
|
|
|
+ [{Sort([fa.IdBirrificio])}
|
|
|
+ [{IndexFilter(Fatture fa, IndFD, fa.Data $>=$ '2020-01-01')}]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ \end{forest}
|
|
|
+\end{center}
|
|
|
+Indice necessario: \texttt{IndFD} (indice della tabella Fatture sull’attributo
|
|
|
+Data).
|
|
|
+Il sort sull'attributo IdBirrificio prima della GroupBy è necessario, in quanto
|
|
|
+i record in input sono ordinati per data, il che non ci garantisce che siano
|
|
|
+raggruppati per IdBirrificio (che è dimensione di analisi).
|
|
|
+
|
|
|
+\subsection{Query c}
|
|
|
+
|
|
|
+\paragraph{Piano di accesso logico della query c}
|
|
|
+\begin{center}
|
|
|
+ \begin{forest}, baseline, qtree
|
|
|
+ [{$\pi^{b}$ fo.RagioneSociale, SUM(fa.Importo) ImportoTotale, AVG(fa.Importo) ImportoMedio}
|
|
|
+ [$\sigma$ SUM(fa.Importo) $>$ 10
|
|
|
+ [{\{fo.IdFornitore, fo.RagioneSociale\} $\gamma$ \{SUM(fa.Importo), AVG(fa.Importo)\}}
|
|
|
+ [{$\bowtie$ fa.IdFornitore = fo.IdFornitore}
|
|
|
+ [{Fornitori fo}]
|
|
|
+ [{$\bowtie$ fa.IdBirrificio = b.IdBirrificio}
|
|
|
+ [{$\sigma$ b.Nome = 'Pirati Rossi'}
|
|
|
+ [{Birrifici b}]
|
|
|
+ ]
|
|
|
+ [{Fatture fa}]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ \end{forest}
|
|
|
+\end{center}
|
|
|
+
|
|
|
+In questo caso non ci dovrebbe essere differenza tra $\pi^{b}$ e $\pi$: non ci
|
|
|
+devono essere due fornitori con la stessa ragione sociale (la ragione sociale
|
|
|
+è chiave naturale); è comunque possibile un errore di inserimento se non ho
|
|
|
+impostato un vincolo di unicità anche su questo attributo, che non ho scelto
|
|
|
+come chiave primaria della tabella.
|
|
|
+\clearpage
|
|
|
+
|
|
|
+\paragraph{Piano di accesso fisico della query c senza indici}
|
|
|
+\begin{center}
|
|
|
+ \begin{forest}, baseline, qtree
|
|
|
+ [{Project(\{fo.RagioneSociale,\\SUM(fa.Importo) ImportoTotale, AVG(fa.Importo) ImportoMedio\})}
|
|
|
+ [{Filter(SUM(fa.Importo) $>$ 10)}
|
|
|
+ [{GroupBy(\{fo.IdFornitore,fo.RagioneSociale\}, \{SUM(fa.Importo), AVG(fa.Importo)\})}
|
|
|
+ [{MergeSort(fa.IdFornitore = fo.IdFornitore)}
|
|
|
+ [{Sort([fo.IdFornitore])}
|
|
|
+ [{Project(\{fo.IdFornitore,\\fo.RagioneSociale\})}
|
|
|
+ [{Fornitori fo}]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ [{Sort([fa.IdFornitore])}
|
|
|
+ [{Project(\{fa.IdFornitore, fa.Importo\})}
|
|
|
+ [{MergeSort(fa.IdBirrificio = b.IdBirrificio)}
|
|
|
+ [{Sort([b.IdBirrificio])}
|
|
|
+ [{Project(\{b.IdBirrificio\})}
|
|
|
+ [{Filter(b.Nome = 'Pirati Rossi')}
|
|
|
+ [{TableScan(Birrifici b)}]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ [{Sort([fa.IdBirrificio])}
|
|
|
+ [{Project(\{fa.IdBirrificio,\\fa.IdFornitore fa.Importo\})}
|
|
|
+ [{Fatture fa}]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ \end{forest}
|
|
|
+\end{center}
|
|
|
+
|
|
|
+\clearpage
|
|
|
+\paragraph{Piano di accesso fisico della query c con due indici}
|
|
|
+\begin{center}
|
|
|
+ \begin{forest}, baseline, qtree
|
|
|
+ [{Project(\{fo.RagioneSociale,\\SUM(fa.Importo) ImportoTotale, AVG(fa.Importo) ImportoMedio\})}
|
|
|
+ [{Filter(SUM(fa.Importo) $>$ 10)}
|
|
|
+ [{GroupBy(\{fo.IdFornitore,fo.RagioneSociale\}, \{SUM(fa.Importo), AVG(fa.Importo)\})}
|
|
|
+ [{MergeSort(fa.IdFornitore = fo.IdFornitore)}
|
|
|
+ [{Sort([fo.IdFornitore])}
|
|
|
+ [{Project(\{fo.IdFornitore,\\fo.RagioneSociale\})}
|
|
|
+ [{Fornitori fo}]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ [{Sort([fa.IdFornitore])}
|
|
|
+ [{Project(\{fa.IdFornitore, fa.Importo\})}
|
|
|
+ [{IndexNestedLoop(fa.IdBirrificio = b.IdBirrificio)}
|
|
|
+ [{IndexFilter(Birrifici b, IndBN,\\b.Nome = 'Pirati Rossi')}]
|
|
|
+ [{IndexFilter(Fatture fa, IndFIdB,\\fa.IdBirrificio = b.IdBirrificio)}]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
]
|
|
|
]
|
|
|
\end{forest}
|
|
|
\end{center}
|
|
|
-Indici necessari: \texttt{IndRC} (indice della tabella R sull’attributo C) e \texttt{IndSF} (indice della tabella S sull'attributo F).
|
|
|
+Indici necessari: \texttt{IndBN} (indice della tabella Birrifici sull’attributo
|
|
|
+Nome) e \texttt{IndFIdB} (indice della tabella Fatture sull'attributo
|
|
|
+IdBirrificio).
|