State all assumptions.
PROJECT (attribute-list) [ SELECT (condition) [ R NATJOIN S ] ]
(a) SELECT(P and Q and M)[ R NATJOIN S ] (b) SELECT(P or Q)[ R NATJOIN S ] (c) PROJECT(E)[ [SELECT(P and Q and M) [R NATJOIN S] ] NATJOIN T ] where R(A,B,C), S(C,D), and T(D,E,F) are relations, P is a predicate over D, Q is a predicate over B, and M is a predicate over C.NOTE: To keep things in ASCII, I am not using special symbols. SELECT(P) is the same as sigma subscript P. R NATJOIN S is the natural join of relations R and S.
You have a clustered unique (no duplicate keys) B+-tree index on attribute A for relation R. Assume this index is kept entirely in memory (i.e., you do not need to read it from disk).
For relation S, you have two indexes:
Furthermore, assume that these two indexes are kept in memory (i.e., you do not need to read them from disk). Also, assume that all of the tuples of S that agree on attribute C are stored in sequentially adjacent blocks on disk (that is, if more than one block is needed to store all of the tuples with some value of C, then these blocks will be sequentially located on the disk).
Other relevant data:
You want to execute the following query:
SELECT * FROM R, S WHERE (R.B=S.B) AND (R.C=S.C)We present you with two query plans:
For every block B of R, retrieved using the clustered index on A for R
For every tuple r of B
Use the index on B for S to retrieve all
of the tuples s of S such that s.B=r.B
For each of these tuples s, if s.C=r.C, output r.A, r.B, r.C,
s.B, s.C, s.D, s.E
For every block B of R, retrieved using the clustered index on A for R
For every tuple r of B
Use the index on C for S to retrieve all
of the tuples s of S such that s.C=r.C
For each of these tuples s, if s.B=r.B, output r.A, r.B, r.C,
s.B, s.C, s.D, s.E