72 ●
P. Mishra and M. H. Eich
in. The amount of reduction in 1/0 activ-
ity (compared to a simple tuple-oriented
implementation) depends on the size of
the available main memory.
A further step toward efficiency con-
sists of “rocking” the inner relation [Kim
1980]. In other words, the inner relation
is read from top to bottom for one tuple of
the outer relation and bottom to top for
the next. This saves on some 1/0 over-
head since the last page of the inner
relation which is retrieved in one loop is
also used in the next loop.
Performance
In the above algorithm, it is seen that
each tuple of the inner relation is com-
pared with every tuple of the outer
relation. Therefore, the simplest imple-
mentation of this algorithm requires 0(
n
x m)
time for execution of joins.
The block-oriented implementation of
the nested-loops join optimizes on 1/0
overhead in the following way. Since the
inner relation is read once for each tuple
in the outer relation, the operation is
most efficient when the relation with the
lower cardinality is chosen as the outer
relation. This reduces the number of
times the inner loop is executed and, con-
sequently, the amount of 1/0 associated
with reading the inner relation, An anal-
ysis of buffer management for the
nested-loops method with rocking shows
that buffering an equal number of pages
for both relations is the best strategy
[Hagmann 1986].
If the join attributes can be accessed
via an index, the algorithm can be made
much more efficient, Such an implemen-
tation has been described in Blasgen and
Eswaran
[1977].
Applicability
The exhaustive matching performed in
this method makes it unsuitable for join-
ing large relations unless the
j’oin selec-
tivity factor, the ratio of the number of
tuples in the result of the join to the total
number of tuples in the Cartesian prod-
uct, is high. If the selectivity factor is
low, the effort of comparing every tuple
in one relation with every tuple in the
other is further unjustified.
The simplicity of this algorithm has
made it a popular choice for hardware
implementation in database machines
[Su 1988]. It has been found that this
algorithm can be parallelized with great
advantage. The parallel version of this
algorithm is found to be more efficient
than most other methods. Thus, we see
that for the nested-loops join, a parallel
implementation of an inefficient serial
algorithm looks good. More details con-
cerning the parallel approach can be
found in Section 6.
This algorithm is also chosen in a pro-
posed model for main memory databases
called the DBGraph storage model
[Pucheral et al. 1990]. The entire
database is represented in terms of a
graph-based data structure called the
DBGraph. A set of primitive operations
is defined to traverse the graph, and all
database operations can be performed us-
ing these primitive operations. Advan -
tages of this model are efficient process-
ing of all database operations and
complex queries, compact storage, and
uniform treatment of permanent and
transient data.
2.2 Sort-Merge Join
The sort-merge join is executed in two
stages. First, both relations are sorted on
the join attributes. Then, both relations
are scanned in the order of the join at-
tributes, and tuples satisfying the join
condition are merged to form a single
relation. Whenever a tuple from the first
relation matches a tuple from the second
relation, the tuples are concatenated and
placed in the output relation.
Algorithm
The exact algorithm for performing a
sort-merge join depends on whether or
not the join attributes are nonkey at-
tributes and on the theta operator. In all
cases, however, it is necessary that the
two relations be physically ordered on
their respective join attributes.
ACM Computing Surveys, Vol 24, No 1, March 1992