mirror of
https://github.com/janishutz/eth-summaries.git
synced 2026-07-27 21:29:09 +02:00
[DMDB] Fix issues, improve query processing with notes on time complexities
This commit is contained in:
@@ -13,4 +13,6 @@
|
||||
\EndProcedure
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
||||
Here, the max output size is $T_R \cdot T_S$, where $T_X$ is the number of tuples for realtion $X$.
|
||||
Here, the max output size is $T_R \cdot T_S$, where $T_X$ is the number of tuples for relation $X$.
|
||||
|
||||
The cost is obviously \cost{$\texttt{cnt}(R) \cdot \texttt{cnt}(S)$}, with $\texttt{cnt}(X)$ the number of tuples in $X$.
|
||||
|
||||
@@ -13,5 +13,5 @@
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
||||
|
||||
The cost here is $P_R + P_R \cdot P_S$ I/Os, where $P_X$ is the number of pages in the relation $X$.
|
||||
The cost here is \cost{$P_R + P_R \cdot P_S$ I/Os}, where $P_X$ is the number of pages in the relation $X$.
|
||||
Furthermore, the DBMS should put the smaller relation on the outer loop to improve performance.
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
||||
|
||||
The cost here is $P_R + T_R \cdot C(I_S)$ I/Os, with $P_X$ the number of pages in the relation $X$, $T_X$ the number of tuples in said relation
|
||||
The cost here is \cost{$P_R + T_R \cdot C(I_S)$ I/Os}, with $P_X$ the number of pages in the relation $X$, $T_X$ the number of tuples in said relation
|
||||
and $C(I_X)$ is the cost to probe the index $I_X$ of relation $X$ and depends on the clustering of data and type of index.
|
||||
|
||||
This operation needs three buffer frames. $1$ for $R$, $1$ for output and $1$ to traverse $I_S$
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
We have $B$ buffer frames, of which one is reserved for the pages of $S$ and one is reserved for the output, thus the $B - 2$ blocks.
|
||||
Each of these blocks houses $P_R / (B - 2))$ pages of $R$, reducing search costs by only scanning $S$ once for every block.
|
||||
|
||||
The cost here is $P_R + (P_R / (B - 2) \cdot P_S$ I/Os.
|
||||
The cost here is \cost{$P_R + (P_R / (B - 2) \cdot P_S$ I/Os}.
|
||||
If however, $R$ fits into memory, we have cost $P_R + P_S$ I/Os.
|
||||
We can reduce that further by building as second step (right after the first for loop) a in-memory hash table for the tuples in the $R$ pages block.
|
||||
This reduces the cost of comparisons, however, we need $(B - 2) \cdot f$ memory now.
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
||||
|
||||
The cost here is $P_R + T_R \cdot C(I_S)$ I/Os.
|
||||
The cost here is \cost{$P_R + T_R \cdot C(I_S)$ I/Os}.
|
||||
We sort the tuples in each buffer frame on the predicate key, which leads to tuples in $R$ with the same key only requiring a single index search.
|
||||
In addition, tuples with ``similar'' values in $R$ will likely match with keys on the same pages of $I_S$, which will already be in the buffer pool.
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
We first sort $R$ and $S$ on the join attributes with external merge sort (see Section~\ref{sec:external-sort}). We then read the sorted files and merge.
|
||||
This is of course not great for performance, but if the relations are already sorted, we can skip the first step.
|
||||
|
||||
The cost (if there are \bi{no duplicates}) is $\texttt{Sort}(S) + \texttt{Sort}(R) + P_R + P_S$ I/Os.
|
||||
The cost (if there are \bi{no duplicates}) is \cost{$\texttt{Sort}(S) + \texttt{Sort}(R) + P_R + P_S$ I/Os}.
|
||||
|
||||
If there are duplicates (i.e. the keys are not unique, say we are joining on a column that doesn't have the UNIQUE constraint)
|
||||
then we need to move the pointer for the join back on the second relation to make sure we don't miss any tuples.
|
||||
|
||||
The cost now of course isn't linear anymore and worst case quadratic, $\tco{\texttt{Sort}(S) + \texttt{Sort}(R) + P_R \cdot P_S}$.
|
||||
The cost now of course isn't linear anymore and worst case quadratic, \cost{$\tco{\texttt{Sort}(S) + \texttt{Sort}(R) + P_R \cdot P_S}$}.
|
||||
|
||||
Compared to BNLJ, its performance doesn't depend on the amount of memory available, but tends to be a tad slower than BNLJ, if BNLJ is provided with ample memory.
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
\subsubsection{Optimized Sort Merge Join ((O)SMJ)}
|
||||
In this section, we are exploring how we can optimize sort and merge with extra memory.
|
||||
|
||||
Sorting can be optimized using replacement sort, the output is $\frac{P_R + P_S}{2B}$ sorted runs of length $2B$.
|
||||
Sorting can be optimized using replacement sort, the output is \cost{$\frac{P_R + P_S}{2B}$} sorted runs of length $2B$.
|
||||
|
||||
That of course means that the logical optimization is to do a $K$-way merge to merge the sorted runs and join the relations at the same time.
|
||||
If we have $B$ frames, so we can do a $B-1$ way merge, otherwise, we merge runs from each relation separately to reduce the number of runs
|
||||
until we have less than $B$ sorted runs, then we perform the join.
|
||||
|
||||
The cost drops to $3 \cdot (P_R + P_S)$ I/Os, but we need memory such that $B^2 \geq \max\{ P_R, P_S \}$
|
||||
The cost drops to \cost{$3 \cdot (P_R + P_S)$ I/Os}, but we need memory such that $B^2 \geq \max\{ P_R, P_S \}$
|
||||
|
||||
@@ -20,4 +20,4 @@ The benefit of this approach is that in the third step, we are only operating on
|
||||
What we ideally do in the above algorithm is to do \textit{recursive partitioning}, i.e. as already \textit{somewhat} described, we partition each partition again,
|
||||
if it has more than one page. This further reduces access times.
|
||||
|
||||
The cost for this is $3 \cdot (P_S + P_R)$, thus both OSMJ and PHJ are very similar in performance.
|
||||
The cost for this is \cost{$3 \cdot (P_S + P_R)$}, thus both OSMJ and PHJ are very similar in performance.
|
||||
|
||||
Reference in New Issue
Block a user