|
@@ -148,7 +148,12 @@ 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.
|
|
|
+come chiave primaria della tabella: ecco perché ho raggruppato anche per
|
|
|
+IdFornitore e non solo per RagioneSociale.
|
|
|
+
|
|
|
+Ho scelto l'ordine di giunzione in modo da avere la restrizione il più distale
|
|
|
+possibile.
|
|
|
+
|
|
|
\clearpage
|
|
|
|
|
|
\paragraph{Piano di accesso fisico della query c senza indici}
|
|
@@ -187,26 +192,30 @@ come chiave primaria della tabella.
|
|
|
]
|
|
|
\end{forest}
|
|
|
\end{center}
|
|
|
+Non è necessario ordinare per \texttt{[fo.IdFornitore, fo.RagioneSociale]} prima
|
|
|
+della GroupBy: per costruzione, l'ordine dell'operatore esterno della SortMerge
|
|
|
+viene mantenuto nell'output, e questo ordine è sull'attributo fo.IdFornitore,
|
|
|
+che a sua volta determina funzionalmente l'altra dimensione di analisi, fo.RagioneSociale.
|
|
|
+
|
|
|
+Pertanto, è garantito che l'input della GroupBy sarà già raggruppato per gli
|
|
|
+attributi che sono dimensione di analisi e non occorre un ordinamento
|
|
|
+preventivo.
|
|
|
|
|
|
\clearpage
|
|
|
-\paragraph{Piano di accesso fisico della query c con due indici}
|
|
|
+\paragraph{Piano di accesso fisico della query c con tre 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)}
|
|
|
+ [{GroupBy(\{fo.IdFornitore, fo.RagioneSociale\},\\\{SUM(fa.Importo), AVG(fa.Importo)\})}
|
|
|
+ [{Sorted([fo.IdFornitore])}
|
|
|
+ [{Project(\{fo.IdFornitore, fo.RagioneSociale, fa.Importo\})}
|
|
|
+ [{IndexNestedLoop(fa.IdFornitore = fo.IdFornitore)}
|
|
|
+ [{IndexNestedLoop\\(fa.IdBirrificio = b.IdBirrificio)}
|
|
|
[{IndexFilter(Birrifici b, IndBN,\\b.Nome = 'Pirati Rossi')}]
|
|
|
- [{IndexFilter(Fatture fa, IndFIdB,\\fa.IdBirrificio = b.IdBirrificio)}]
|
|
|
+ [{IndexFilter(Fatture fa, IndFaIdB,\\fa.IdBirrificio = b.IdBirrificio)}]
|
|
|
]
|
|
|
+ [{IndexFilter(Fornitori fo, IndFoIdF,\\fo.IdFornitore = fa.IdFornitore)}]
|
|
|
]
|
|
|
]
|
|
|
]
|
|
@@ -216,5 +225,27 @@ come chiave primaria della tabella.
|
|
|
\end{forest}
|
|
|
\end{center}
|
|
|
Indici necessari: \texttt{IndBN} (indice della tabella Birrifici sull’attributo
|
|
|
-Nome) e \texttt{IndFIdB} (indice della tabella Fatture sull'attributo
|
|
|
-IdBirrificio).
|
|
|
+Nome), \texttt{IndFaIdB} (indice della tabella Fatture sull'attributo
|
|
|
+IdBirrificio) e \texttt{IndFoIdF} (indice della tabella Fornitori sull'attributo
|
|
|
+IdFornitore).
|
|
|
+
|
|
|
+Occorre ordinare per IdFornitore prima della \texttt{GroupBy}, in quanto
|
|
|
+l'output della IndexNestedLoop è ordinato come l'operatore esterno, ovvero
|
|
|
+per nome del birrificio.
|
|
|
+
|
|
|
+Potrei spostare l'ordinamento tra le due giunzioni con IndexNestedLoop, tanto
|
|
|
+ogni fattura ha un fornitore e l'output non andrà a decrecere dopo la seconda
|
|
|
+giunzione (anzi, si arricchirà di campi).
|
|
|
+Il sort andrebbe fatto con il minor numero possibile di dati, dato l'alto costo
|
|
|
+dell'algoritmo, eliminando i campi superflui con una project prima.
|
|
|
+
|
|
|
+Il vantaggio dell'IndexNestedLoop sul SortMerge si ha solo se la condizione è
|
|
|
+sufficientemente restrittiva da essere soddisfatta da una piccola minoranza
|
|
|
+di record.
|
|
|
+In questo caso, la restrizione sul nome del birrificio dovrebbe essere
|
|
|
+abbastanza restrittiva (se ci sono abbastanza birrifici, il numero di
|
|
|
+birrifici con il nome `Pirati Rossi' sarà trascurabile rispetto al totale) ed
|
|
|
+è ragionevole che le fatture che riguardano quel birrificio siano una esigua
|
|
|
+minoranza rispetto al totale delle fatture.
|
|
|
+Se così non fosse, pur avendo i tre indici a disposizione, converrebbe
|
|
|
+utilizzare comunque il SortMerge.
|