Iterators, Joins, and Relational Algebra
Discussion 6
Announcements
Agenda
Iterators
Iterators
Iterators
Iterators
Joins
Joins
Joins
Simple Nested Loop Join (SNLJ)
Which relation should we pick as R and S respectively?
Worksheet Q1a
How many disk I/Os are needed to perform a simple nested loop join?
Companies: (company_id, industry, ipo_date)
Nyse: (company_id, date, trade, quantity)
Worksheet Q1a
How many disk I/Os are needed to perform a simple nested loop join?
Companies: (company_id, industry, ipo_date)
Nyse: (company_id, date, trade, quantity)
C ⋈ N
Cost is [C] + |C| * [N] = [C] + pC [C] [N]
= 50 + 50 * 50 * 100 = 250,050 I/Os
N ⋈ C
Cost is [N] + |N| * [C] = [N] + pN [N] [C]
= 100 + 100 * 100 * 50 = 500,100 I/Os
I/O cost for SNLJ: min(500,100, 250,050) = 250,050 I/Os
Page Nested Loop Join (PNLJ)
Page Nested Loop Join (PNLJ)
Page Nested Loop Join (PNLJ)
Page Nested Loop Join (PNLJ)
Block Nested Loop Join (BNLJ)
Block Nested Loop Join (BNLJ)
Block Nested Loop Join (BNLJ)
R
S
B = 4
Output Buffer
R
S
B = 4
Output Buffer
R
S
B = 4
Output Buffer
R
S
B = 4
Output Buffer
R
S
B = 4
Output Buffer
R
S
B = 4
Output Buffer
R
S
B = 4
Output Buffer
R
S
B = 4
Output Buffer
BNLJ
Worksheet Q1b
How many disk I/Os are needed to perform a block nested loop join?
Companies: (company_id, industry, ipo_date)
Nyse: (company_id, date, trade, quantity)
Worksheet Q1b
How many disk I/Os are needed to perform a block nested loop join?
Companies: (company_id, industry, ipo_date)
Nyse: (company_id, date, trade, quantity)
B = 20, block size = B - 2 = 18
C ⋈ N
Cost is [C] + ⌈[C] / B - 2⌉ * [N]
= 50 + ⌈50 / 18⌉ * 100 = 350 I/Os
N ⋈ C
Cost is [N] + ⌈[N] / B - 2⌉ * [C]
= 100 + ⌈100 / 18⌉ * 50 = 400 I/Os
I/O cost for BNLJ: min(350, 400) I/Os = 350 I/Os
Index Nested Loop Join (INLJ)
Index Nested Loop Join (INLJ)
(found using the index):
Index Nested Loop Join (INLJ)
Index Nested Loop Join (INLJ)
Index Nested Loop Join (INLJ)
Index on S.col
43 |
5 |
11 |
R.col
Output
Index Nested Loop Join (INLJ)
Index on S.col
43 |
5 |
11 |
R.col
Output
Index Nested Loop Join (INLJ)
Index on S.col
43 |
5 |
11 |
R.col
not a match
Output
Index Nested Loop Join (INLJ)
Index on S.col
43 |
5 |
11 |
R.col
Output
Index Nested Loop Join (INLJ)
Index on S.col
43 |
5 |
11 |
R.col
Output
Worksheet Q1c
How many disk I/Os are needed to perform an index nested loop join?
Companies: (company_id, industry, ipo_date)
Nyse: (company_id, date, trade, quantity)
Worksheet Q1c
How many disk I/Os are needed to perform an index nested loop join?
Companies: (company_id, industry, ipo_date)
Nyse: (company_id, date, trade, quantity)
C ⋈ N
Cost is [C] + |C| * cost of searching N
= 50 + (50 * 50) * (2 + 4) = 15,050 I/Os
N ⋈ C
Cost is [N] + |N| * cost of searching C
= 100 + (100 * 100) * (2 + 1) = 30,100 I/Os
I/O cost: min(30,100, 15,050) = 15,050 I/Os
Worksheet Q1d
Now assume the index on NYSE.company_id is clustered. What is the cost of an index nested loop join using companies as the outer relation?
Companies: (company_id, industry, ipo_date)
Nyse: (company_id, date, trade, quantity)
Worksheet Q1d
Now assume the index on NYSE.company_id is clustered. What is the cost of an index nested loop join using companies as the outer relation?
Companies: (company_id, industry, ipo_date)
Nyse: (company_id, date, trade, quantity)
C ⋈ N
Cost is [C] + |C| * cost of searching N
= 50 + 50 * 50 * (2 + # pages of matching tuples)
= 50 + 50 * 50 * (2 + ceil(# matches /pN ) )
= 50 + 50 * 50 * (2 + ceil(4/100)) = 7550 I/Os
Sort-Merge Join (SMJ)
Sort-Merge Join (SMJ)
Sort-Merge Join (SMJ)
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
31 | lubber | 101 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
31 | lubber | 101 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
31 | lubber | 101 |
31 | lubber | 102 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
31 | lubber | 101 |
31 | lubber | 102 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
31 | lubber | 101 |
31 | lubber | 102 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
31 | lubber | 101 |
31 | lubber | 102 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
31 | lubber | 101 |
31 | lubber | 102 |
31 | lubber2 | 101 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
31 | lubber | 101 |
31 | lubber | 102 |
31 | lubber2 | 101 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
31 | lubber | 101 |
31 | lubber | 102 |
31 | lubber2 | 101 |
31 | lubber2 | 102 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
31 | lubber | 101 |
31 | lubber | 102 |
31 | lubber2 | 101 |
31 | lubber2 | 102 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
31 | lubber | 101 |
31 | lubber | 102 |
31 | lubber2 | 101 |
31 | lubber2 | 102 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
31 | lubber | 101 |
31 | lubber | 102 |
31 | lubber2 | 101 |
31 | lubber2 | 102 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
31 | lubber | 101 |
31 | lubber | 102 |
31 | lubber2 | 101 |
31 | lubber2 | 102 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
31 | lubber | 101 |
31 | lubber | 102 |
31 | lubber2 | 101 |
31 | lubber2 | 102 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
31 | lubber | 101 |
31 | lubber | 102 |
31 | lubber2 | 101 |
31 | lubber2 | 102 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
31 | lubber | 101 |
31 | lubber | 102 |
31 | lubber2 | 101 |
31 | lubber2 | 102 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
31 | lubber | 101 |
31 | lubber | 102 |
31 | lubber2 | 101 |
31 | lubber2 | 102 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
31 | lubber | 101 |
31 | lubber | 102 |
31 | lubber2 | 101 |
31 | lubber2 | 102 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
31 | lubber | 101 |
31 | lubber | 102 |
31 | lubber2 | 101 |
31 | lubber2 | 102 |
Sort-Merge Join
sid | sname |
22 | dustin |
28 | yuppy |
31 | lubber |
31 | lubber2 |
44 | guppy |
57 | rusty |
sid | bid |
28 | 103 |
28 | 104 |
31 | 101 |
31 | 102 |
42 | 142 |
58 | 107 |
while not done {
while (r < s) { advance r }
while (r > s) { advance s }
mark s // save start of “block”
while (r == s) {
// Outer loop over r
while (r == s) {
// Inner loop over s
yield <r, s>
advance s
}
reset s to mark
advance r
}
}
sid | sname | bid |
28 | yuppy | 103 |
28 | yuppy | 104 |
31 | lubber | 101 |
31 | lubber | 102 |
31 | lubber2 | 101 |
31 | lubber2 | 102 |
Sort-Merge Join (SMJ)
Sort-Merge Join (SMJ)
Sort-Merge Join (SMJ)
Worksheet Q1e
In the average case, how many disk I/Os are needed to perform a sort-merge join (unoptimized/optimized)?
Companies: (company_id, industry, ipo_date)
Nyse: (company_id, date, trade, quantity)
Worksheet Q1e
How many disk I/Os are needed to perform a sort-merge join (unoptimized/optimized)?
Companies: (company_id, industry, ipo_date)
Nyse: (company_id, date, trade, quantity)
Unoptimized:
Sorting N:
Pass 1 - ceil(100/20) = 5 sorted runs of 20 pages each
Pass 2 - ceil(5/19) = 1 sorted run of 100 pages each
Total I/Os: 4 * (100 pages) = 400 I/Os
Sorting C:
Pass 1 - ceil(50/20) = 3 sorted runs of 20 pages, 20 pages, and 10 pages
Pass 2 - ceil(3/19) = 1 sorted run of 50 pages
Total I/Os: 4 * (50 pages) = 200 I/Os
Merging: [C] + [N] = 150 I/Os
Total SMJ I/Os: 200 + 400 + 150 = 750 I/Os
1 sorted run of 20 pages
1 sorted run of 20 pages
1 sorted run of 20 pages
1 sorted run of 20 pages
1 sorted run of 20 pages
1 input buffer
1 input buffer
…
1 input buffer
1 output buffer
1 sorted run of 100 pages
100
100
Sorted Runs of N
20 Buffers
100 pages
Relation N
100
100
I/Os:
Sorted Relation N
Read, Write, Merge
Unoptimized SMJ
1 sorted run of 20 pages
1 sorted run of 20 pages
1 sorted run of 10 pages
1 input buffer
1 input buffer
…
1 input buffer
1 output buffer
1 sorted run of 50 pages
50
50
Sorted Runs of C
20 Buffers
50 pages
Relation C
50
50
I/Os:
1 sorted run of 100 pages
Sorted Relation N
Sorted Relation C
Read, Write, Merge
Unoptimized SMJ
1 sorted run of 50 pages
I/Os: 750
1 sorted run of 100 pages
Sorted Relation N
Sorted Relation C
Joined Relation C and N
150
Read, Write, Merge
Unoptimized SMJ
Worksheet Q1e
How many disk I/Os are needed to perform a sort-merge join (unoptimized/optimized)?
Companies: (company_id, industry, ipo_date)
Nyse: (company_id, date, trade, quantity)
Can we perform the SMJ optimization?
Sorting N:
Pass 1 - ceil(100/20) = 5 sorted runs of 20 pages each
Pass 2 - ceil(5/19) = 1 sorted run of 100 pages each
Total I/Os: 4 * (100 pages) = 400 I/Os
Sorting C:
Pass 1 - ceil(50/20) = 3 sorted runs of 20 pages, 20 pages, and 10 pages
Pass 2 - ceil(3/19) = 1 sorted run of 50 pages
Total I/Os: 4 * (50 pages) = 200 I/Os
Worksheet Q1e
How many disk I/Os are needed to perform a sort-merge join (unoptimized/optimized)?
Companies: (company_id, industry, ipo_date)
Nyse: (company_id, date, trade, quantity)
Can we perform the SMJ optimization?
Yes.
During the 2nd to last pass, we produce 5 sorted runs of N and 3 sorted runs of C. Since the number of runs of C + the number of runs of N ≤ 20 - 1, we can optimize sort merge join and combine the last sorting pass and final merging pass to save 2 * ([C] + [N]) I/Os.
Total I/Os = 750 - 2(50+100) = 450 I/Os
1 sorted run of 20 pages
1 sorted run of 20 pages
1 sorted run of 20 pages
1 sorted run of 20 pages
1 sorted run of 20 pages
1 input buffer
1 input buffer
…
1 input buffer
1 output buffer
100
Sorted Runs of N
20 Buffers
100 pages
Relation N
100
100
I/Os: cost(unoptimized SMJ) - 2([C] + [N])
= 750 - 2(150)
= 450
Read, Write
Optimized SMJ
1 sorted run of 20 pages
1 sorted run of 20 pages
1 sorted run of 10 pages
50
Sorted Runs of C
50 pages
Relation C
50
50
Joined Relation C and N
N and C are streamed to join operation!
Criteria for optimization:
# of runs for N + # of runs for S <= B-1
5 + 3 <= 19 ✔
Grace Hash Join
Grace Hash Join
Grace Hash Join: Partition
Grace Hash Join: Partition
Grace Hash Join: Partition
Grace Hash Join: Partition
Grace Hash Join: Partition
Grace Hash Join: Partition
Grace Hash Join: Partition
Grace Hash Join: Partition
Grace Hash Join: Partition
Grace Hash Join: Partition
Grace Hash Join: Partition
Grace Hash Join: Partition
Grace Hash Join: Partition
Grace Hash Join
Grace Hash Join
Pass 2: Build and Probe
Grace Hash Join: Build & Probe
Build in-memory hash table of R and stream in tuples of S
Grace Hash Join: Build & Probe
Build in-memory hash table of R and stream in tuples of S
Grace Hash Join: Build & Probe
Probe in-memory hash table of R and stream out matching tuples of S and R
Grace Hash Join: Build & Probe
Probe in-memory hash table of R and stream out matching tuples of S and R
Grace Hash Join: Build & Probe
Probe in-memory hash table of R and stream out matching tuples of S and R
Grace Hash Join: Build & Probe
Probe in-memory hash table of R and stream out matching tuples of S and R
Grace Hash Join: Build & Probe
Build in-memory hash table of R and stream in tuples of S
Grace Hash Join: Build & Probe
Build in-memory hash table of R and stream in tuples of S
Grace Hash Join: Build & Probe
Probe in-memory hash table of R and stream out matching tuples of S and R
Grace Hash Join: Build & Probe
Probe in-memory hash table of R and stream out matching tuples of S and R
Grace Hash Join: Build & Probe
Probe in-memory hash table of R and stream out matching tuples of S and R
Grace Hash Join: Build & Probe
Probe in-memory hash table of R and stream out matching tuples of S and R
Grace Hash Join: Build & Probe
…
Probe in-memory hash table of R and stream out matching tuples of S and R
Worksheet
Worksheet Q2a
If we had 10 buffer pages, how many partitioning phases would we require for grace hash join?
Worksheet Q2a
If we had 10 buffer pages, how many partitioning phases would we require for grace hash join?
T is smaller, so we need its partitions to be at most B - 2 = 8 pages. After 1 partitioning pass, we have partitions of size 6, which is <= 8 so we only need 1 partitioning pass.
Worksheet Q2b
What is the IO cost for the grace hash join then? Assume uniform partitioning.
Worksheet Q2b
What is the IO cost for the grace hash join then? Assume uniform partitioning.
We need 1 partitioning pass.
Partitioning phase:
ceil([C]/(B - 1)) = 12 pages per partition for C, 12(9) pages in total after partitioning
ceil([T]/(B - 1)) = 6 pages per partition for T, 6(9) pages in total after partitioning
Partitioning IOs: 100 I/Os to read from Catalog + 12(9) to write for Catalog + 50 I/Os to read from Transactions + 6(9) to write for Transactions = 312 I/Os
Probing phase: 12(9) + 6(9) = 162 I/Os to read from Catalog and Transactions
Total: 312 + 162 = 474 I/Os
Worksheet Q2c
If we only had 8 buffer pages, how many partitioning phases would there be?
Worksheet Q2c,d
disk
disk
15 pages of C | 8 pages of T |
100 pages of C | 50 pages of T |
Read into memory
7 partitions, each with
Write to disk
In memory:
Using 1 input buffer,
B-1 = 7 output buffers
Pass 1: Partition
The partitions for neither table fit in B-2 = 6 pages, so we must recursively partition.
3 pages of C | 2 pages of T |
49 partitions, each with
In memory:
Using 1 input buffer,
B-1 = 7 output buffers
disk
Write to disk
Read into memory
Pass 2: Partition
The partitions for at least 1 table fit in B-2 = 6 pages, so we can enter the Build and Probe phase.
Worksheet Q2c,d
disk
B-2 buffer pages:
Hash Table on C
1 Input Buffer
1 Output Buffer
Read into memory
Stream output into next operator
Exclude I/O cost of final write!
Build and Probe
3 pages of C | 2 pages of T |
49 partitions, each with
Worksheet Q2c,d
disk
B-2 buffer pages:
Hash Table on T
1 Input Buffer
1 Output Buffer
Read into memory
Stream output into next operator
Exclude I/O cost of final write!
Build and Probe
3 pages of C | 2 pages of T |
49 partitions, each with
Note: We can alternatively build a hash table on T and probe C since partitions for either relation fit in B-2 pages.
Worksheet Q2c
If we only had 8 buffer pages, how many partitioning phases would there be?
T is smaller, so we need its partitions to be at most B - 2 = 6 pages. After 1 partitioning pass,
we have partitions of size 8, which is too big to fit in B-2 buffer pages. We need a second
partitioning pass. 8 / 7 = 1.1→2 pages, which is small enough to fit in B-2 buffer pages.
Therefore, we need 2 passes in total.
Worksheet Q2d
What will be the IO cost?
Worksheet Q2d
What will be the IO cost?
Partitioning phase:
ceil([C]/(B - 1)) = 15 pages per partition for C
ceil([T]/(B - 1)) = 8 pages per partition for T
ceil([C]/(B - 1)) = 3 pages per partition for second pass for C
ceil([T]/(B - 1)) = 2 pages per partition for second pass for T
Read 1st Write 1st Read 2nd Write 2nd
Partitioning IOs: [100 + 50] + [15(7) + 8(7)] + [15(7) + 8(7)] + [3(49) + 2(49)] = 717 I/Os
Build and Probe Phase: 3(49) + 2(49) = 245 IOs
Total: 717 + 245 = 962 I/Os
Relational Algebra
Relational Algebra
Relational Algebra: Unary Operators
Relational Algebra: Unary Operators
Relational Algebra: Unary Operators
Relational Algebra: Binary Operators
Relational Algebra: Binary Operators
Relational Algebra: Binary Operators
Relational Algebra: Compound Operators
R — (R — S)
Relational Algebra: Compound Operators
σ𝜃(R × S)
Relational Algebra: Compound Operators
σR.col1=S.col1 ∧ … ∧ R.colN=S.colN (R × S)
Relational Algebra: Extensions
Relational Algebra: Nested Queries Example 1
SELECT cats.name
FROM cats
WHERE cats.name NOT IN
(SELECT dogs.name
FROM dogs)
πcats.name(cats) —
πcats.name (cats ⋈cats.name = dogs.name dogs)
Relational Algebra: Nested Queries Example 2
SELECT cats.name
FROM cats
WHERE cats.name IN
(SELECT dogs.name
FROM dogs)
πcats.name(cats) ∩ πdogs.name(dogs)
alternatively,
πcats.name (cats ⋈cats.name = dogs.name dogs)
Worksheet 3a: Relational Algebra
Find the name of the artists who have albums with a genre of either ‘pop’ or ‘rock’.
Tables
Songs �(song_id, song_name, album_id, weeks_in_top_40)
Artists �(artist_id, artist_name, first_year_active)
Albums �(album_id, album_name, artist_id, year_released, genre)
Worksheet 3a: Relational Algebra
Find the name of the artists who have albums with a genre of either ‘pop’ or ‘rock’.
Tables
Songs �(song_id, song_name, album_id, weeks_in_top_40)
Artists �(artist_id, artist_name, first_year_active)
Albums �(album_id, album_name, artist_id, year_released, genre)
πartist_name(
σgenre = ‘pop’ ∨ genre = ‘rock’ (Artists ⋈ Albums)
)
Worksheet 3b: Relational Algebra
Find the name of the artists who have albums of genre ‘pop’ and ‘rock’.
Tables
Songs �(song_id, song_name, album_id, weeks_in_top_40)
Artists �(artist_id, artist_name, first_year_active)
Albums �(album_id, album_name, artist_id, year_released, genre)
Worksheet 3b: Relational Algebra
Find the name of the artists who have albums of genre ‘pop’ and ‘rock’.
Tables
Songs �(song_id, song_name, album_id, weeks_in_top_40)
Artists �(artist_id, artist_name, first_year_active)
Albums �(album_id, album_name, artist_id, year_released, genre)
πartist_name(
Artists ⋈ (
πartist_id(σgenre = ‘pop’ (Albums)) ∩
πartist_id(σgenre = ‘rock’ (Albums))
)
)
Worksheet 3c: Relational Algebra
Find the id of the artists who have albums of genre ‘pop’ or have spent over 10 weeks in the top 40.
Tables
Songs �(song_id, song_name, album_id, weeks_in_top_40)
Artists �(artist_id, artist_name, first_year_active)
Albums �(album_id, album_name, artist_id, year_released, genre)
Worksheet 3c: Relational Algebra
Find the id of the artists who have albums of genre ‘pop’ or have spent over 10 weeks in the top 40.
Tables
Songs �(song_id, song_name, album_id, weeks_in_top_40)
Artists �(artist_id, artist_name, first_year_active)
Albums �(album_id, album_name, artist_id, year_released, genre)
πartist_id(σgenre = ‘pop’ (Albums)) ∪
πartist_id(σweeks_in_top_40 > 10 (Albums ⋈ Songs))
Worksheet 3d: Relational Algebra
Find the names of all artists who do not have any albums.
Tables
Songs �(song_id, song_name, album_id, weeks_in_top_40)
Artists �(artist_id, artist_name, first_year_active)
Albums �(album_id, album_name, artist_id, year_released, genre)
Worksheet 3d: Relational Algebra
Find the names of all artists who do not have any albums.
Tables
Songs �(song_id, song_name, album_id, weeks_in_top_40)
Artists �(artist_id, artist_name, first_year_active)
Albums �(album_id, album_name, artist_id, year_released, genre)
πartist_name(
Artists ⋈ (
πartist_id(Artists) —
πartist_id(Albums)
)
)
Attendance Link