Skip to content

Commit cf3349d

Browse files
committed
Fixed selinger1979access formatting.
1 parent 9b55f10 commit cf3349d

File tree

2 files changed

+259
-153
lines changed

2 files changed

+259
-153
lines changed

html/selinger1979access.html

Lines changed: 160 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -32,103 +32,207 @@ <h2 id="costs-for-single-relation-access-paths">Costs for Single Relation Access
3232
<p>The WHERE clause of a query is considered in conjunctive normal form, and each conjunct is called a <strong>boolean factor</strong>. The query optimizer estimates a <strong>selectivity factor</strong> <code>F</code> for each boolean factor with the following rules.</p>
3333
<table>
3434
<tr>
35-
<pre><code>&lt;td&gt;`column = value`&lt;/td&gt;
36-
&lt;td&gt;`F = 1 / ICARD(column index)`&lt;/td&gt;
37-
&lt;td&gt;If there exists an index.&lt;/td&gt;</code></pre>
35+
<td>
36+
<code>column = value</code>
37+
</td>
38+
<td>
39+
<code>F = 1 / ICARD(column index)</code>
40+
</td>
41+
<td>
42+
If there exists an index.
43+
</td>
3844
</tr>
3945
<tr>
40-
<pre><code>&lt;td&gt;`column = value`&lt;/td&gt;
41-
&lt;td&gt;`F = 1 / 10`&lt;/td&gt;
42-
&lt;td&gt;If there does not exist an index.&lt;/td&gt;</code></pre>
46+
<td>
47+
<code>column = value</code>
48+
</td>
49+
<td>
50+
<code>F = 1 / 10</code>
51+
</td>
52+
<td>
53+
If there does not exist an index.
54+
</td>
4355
</tr>
4456
<tr>
45-
<pre><code>&lt;td&gt;`column1 = column2`&lt;/td&gt;
46-
&lt;td&gt;`F = 1 / MAX(ICARD(columnn1 index), ICARD(columnn2 index))`&lt;/td&gt;
47-
&lt;td&gt;If there exists two indexes.&lt;/td&gt;</code></pre>
57+
<td>
58+
<code>column1 = column2</code>
59+
</td>
60+
<td>
61+
<code>F = 1 / MAX(ICARD(columnn1 index), ICARD(columnn2 index))</code>
62+
</td>
63+
<td>
64+
If there exists two indexes.
65+
</td>
4866
</tr>
4967
<tr>
50-
<pre><code>&lt;td&gt;`column1 = column2`&lt;/td&gt;
51-
&lt;td&gt;`F = 1 / ICARD(columnni index)`&lt;/td&gt;
52-
&lt;td&gt;If there exists one index.&lt;/td&gt;</code></pre>
68+
<td>
69+
<code>column1 = column2</code>
70+
</td>
71+
<td>
72+
<code>F = 1 / ICARD(columnni index)</code>
73+
</td>
74+
<td>
75+
If there exists one index.
76+
</td>
5377
</tr>
5478
<tr>
55-
<pre><code>&lt;td&gt;`column1 = column2`&lt;/td&gt;
56-
&lt;td&gt;`F = 1 / 10`&lt;/td&gt;
57-
&lt;td&gt;If there does not exist an index.&lt;/td&gt;</code></pre>
79+
<td>
80+
<code>column1 = column2</code>
81+
</td>
82+
<td>
83+
<code>F = 1 / 10</code>
84+
</td>
85+
<td>
86+
If there does not exist an index.
87+
</td>
5888
</tr>
5989
<tr>
60-
<pre><code>&lt;td&gt;`column &gt; value`&lt;/td&gt;
61-
&lt;td&gt;`F = (high key - value) / (high key - low key)`&lt;/td&gt;
62-
&lt;td&gt;If `column` is arithmetic.&lt;/td&gt;</code></pre>
90+
<td>
91+
<code>column &gt; value</code>
92+
</td>
93+
<td>
94+
<code>F = (high key - value) / (high key - low key)</code>
95+
</td>
96+
<td>
97+
If <code>column</code> is arithmetic.
98+
</td>
6399
</tr>
64100
<tr>
65-
<pre><code>&lt;td&gt;`column &gt; value`&lt;/td&gt;
66-
&lt;td&gt;`F = 1/3`&lt;/td&gt;
67-
&lt;td&gt;If `column` is not arithmetic.&lt;/td&gt;</code></pre>
101+
<td>
102+
<code>column &gt; value</code>
103+
</td>
104+
<td>
105+
<code>F = 1/3</code>
106+
</td>
107+
<td>
108+
If <code>column</code> is not arithmetic.
109+
</td>
68110
</tr>
69111
<tr>
70-
<pre><code>&lt;td&gt;`column BETWEEN value1 AND value2`&lt;/td&gt;
71-
&lt;td&gt;`F = (value2 - value1) / (high key - low key)`&lt;/td&gt;
72-
&lt;td&gt;If `column` is not arithmetic.&lt;/td&gt;</code></pre>
112+
<td>
113+
<code>column BETWEEN value1 AND value2</code>
114+
</td>
115+
<td>
116+
<code>F = (value2 - value1) / (high key - low key)</code>
117+
</td>
118+
<td>
119+
If <code>column</code> is not arithmetic.
120+
</td>
73121
</tr>
74122
<tr>
75-
<pre><code>&lt;td&gt;`column BETWEEN value1 AND value2`&lt;/td&gt;
76-
&lt;td&gt;`F = 1/4`&lt;/td&gt;
77-
&lt;td&gt;If `column` is not arithmetic.&lt;/td&gt;</code></pre>
123+
<td>
124+
<code>column BETWEEN value1 AND value2</code>
125+
</td>
126+
<td>
127+
<code>F = 1/4</code>
128+
</td>
129+
<td>
130+
If <code>column</code> is not arithmetic.
131+
</td>
78132
</tr>
79133
<tr>
80-
<pre><code>&lt;td&gt;`column IN (list of values)`&lt;/td&gt;
81-
&lt;td&gt;`F = (number of items in list) * (F for column=value)`&lt;/td&gt;
82-
&lt;td&gt;Capped at `1/2`.&lt;/td&gt;</code></pre>
134+
<td>
135+
<code>column IN (list of values)</code>
136+
</td>
137+
<td>
138+
<code>F = (number of items in list) * (F for column=value)</code>
139+
</td>
140+
<td>
141+
Capped at <code>1/2</code>.
142+
</td>
83143
</tr>
84144
<tr>
85-
<pre><code>&lt;td&gt;`column IN subquery`&lt;/td&gt;
86-
&lt;td&gt;`F = (expected cardinality of subquery result) /
87-
(product of subquery FROM cardinalities)`&lt;/td&gt;
88-
&lt;td&gt;&lt;/td&gt;</code></pre>
145+
<td>
146+
<code>column IN subquery</code>
147+
</td>
148+
<td>
149+
<code>F = (expected cardinality of subquery result) / (product of subquery FROM cardinalities)</code>
150+
</td>
151+
<td>
152+
</td>
89153
</tr>
90154
<tr>
91-
<pre><code>&lt;td&gt;`a OR b`&lt;/td&gt;
92-
&lt;td&gt;`F = F(a) + F(b) - F(a)*F(b)`&lt;/td&gt;
93-
&lt;td&gt;&lt;/td&gt;</code></pre>
155+
<td>
156+
<code>a OR b</code>
157+
</td>
158+
<td>
159+
<code>F = F(a) + F(b) - F(a)*F(b)</code>
160+
</td>
161+
<td>
162+
</td>
94163
</tr>
95164
<tr>
96-
<pre><code>&lt;td&gt;`a AND b`&lt;/td&gt;
97-
&lt;td&gt;`F = F(a)*F(b)`&lt;/td&gt;
98-
&lt;td&gt;&lt;/td&gt;</code></pre>
165+
<td>
166+
<code>a AND b</code>
167+
</td>
168+
<td>
169+
<code>F = F(a)*F(b)</code>
170+
</td>
171+
<td>
172+
</td>
99173
</tr>
100174
<tr>
101-
<pre><code>&lt;td&gt;`NOT a`&lt;/td&gt;
102-
&lt;td&gt;`F = 1 - F(a)`&lt;/td&gt;
103-
&lt;td&gt;&lt;/td&gt;</code></pre>
175+
<td>
176+
<code>NOT a</code>
177+
</td>
178+
<td>
179+
<code>F = 1 - F(a)</code>
180+
</td>
181+
<td>
182+
</td>
104183
</tr>
105184
</table>
106185
<p>The cardinality of query (QCARD) is the product of the sizes of the relations in the FROM clause multiplied by the selectivity factor of every boolean factor in the WHERE clause. The number of RSI calls (RSICARD) is the product of the sizes of the relations in the FROM clause multiplied by the selectivity of the sargable boolean factors.</p>
107186
<p>Some access paths produce tuples in a particular order. For example, an index scan produces tuples in the order of the index key. If this order is consistent with the order of a GROUP BY or ORDER BY clause, we say it is an <strong>interesting order</strong>. The query optimizer computes the minimum cost unordered plan and the minimum cost plan for every interesting order. After taking into account the (potential) additional overhead of sorting unordered tuples for a GROUP BY or ORDER BY, the least cost plan is selected.</p>
187+
<p>The following costs include the number of index pages fetched, then the number of data pages fetched, and then the number of RSI calls weighted by <code>W</code>.</p>
108188
<table>
109189
<tr>
110-
<pre><code>&lt;td&gt;Unique index matching an equal predicate.&lt;/td&gt;
111-
&lt;td&gt;`1 + 1 + W`&lt;/td&gt;</code></pre>
190+
<td>
191+
Unique index matching an equal predicate.
192+
</td>
193+
<td>
194+
<code>1 + 1 + W</code>
195+
</td>
112196
</tr>
113197
<tr>
114-
<pre><code>&lt;td&gt;Clustered index `I` matching one or more boolean factors.&lt;/td&gt;
115-
&lt;td&gt;`F(preds)*(NINDX(I) + TCARD) + W*RSICARD`&lt;/td&gt;</code></pre>
198+
<td>
199+
Clustered index <code>I</code> matching one or more boolean factors.
200+
</td>
201+
<td>
202+
<code>F(preds)*(NINDX(I) + TCARD) + W*RSICARD</code>
203+
</td>
116204
</tr>
117205
<tr>
118-
<pre><code>&lt;td&gt;Non-clustered index `I` matching one or more boolean factors.&lt;/td&gt;
119-
&lt;td&gt;`F(preds)*(NINDX(I) + NCARD) + W*RSICARD`&lt;/td&gt;</code></pre>
206+
<td>
207+
Non-clustered index <code>I</code> matching one or more boolean factors.
208+
</td>
209+
<td>
210+
<code>F(preds)*(NINDX(I) + NCARD) + W*RSICARD</code>
211+
</td>
120212
</tr>
121213
<tr>
122-
<pre><code>&lt;td&gt;Clustered index `I` not matching any boolean factors&lt;/td&gt;
123-
&lt;td&gt;`NINDX(I) + TCARD + W*RSICARD`&lt;/td&gt;</code></pre>
214+
<td>
215+
Clustered index <code>I</code> not matching any boolean factors
216+
</td>
217+
<td>
218+
<code>NINDX(I) + TCARD + W*RSICARD</code>
219+
</td>
124220
</tr>
125221
<tr>
126-
<pre><code>&lt;td&gt;Non-clustered index `I` not matching any boolean factors&lt;/td&gt;
127-
&lt;td&gt;NINDX(I) + NCARD + W*RSICARD&lt;/td&gt;</code></pre>
222+
<td>
223+
Non-clustered index <code>I</code> not matching any boolean factors
224+
</td>
225+
<td>
226+
<code>NINDX(I) + NCARD + W*RSICARD</code>
227+
</td>
128228
</tr>
129229
<tr>
130-
<pre><code>&lt;td&gt;Segment scan.&lt;/td&gt;
131-
&lt;td&gt;TCARD/P + W*RSICARD&lt;/td&gt;</code></pre>
230+
<td>
231+
Segment scan.
232+
</td>
233+
<td>
234+
<code>TCARD/P + W*RSICARD</code>
235+
</td>
132236
</tr>
133237
</table>
134238
<h2 id="access-path-selection-for-joins">Access Path Selection for Joins</h2>
@@ -137,7 +241,7 @@ <h2 id="access-path-selection-for-joins">Access Path Selection for Joins</h2>
137241
<p>The query optimizer performs a couple of tricks to speed up this algorithm. First, it does not consider a cross-join if there are other more selective joins possible. Second, it computes interesting order equivalence classes to avoid computing redundant interesting orders. For example, if there are predicates <code>E.DNO = D.DNO</code> and <code>D.DNO = F.DNO</code>, then all three columns belong to the same equivalence class.</p>
138242
<p>This algorithm computes at worst (2<sup>n</sup> times the number of interesting orders) intermediate access paths.</p>
139243
<h2 id="nested-queries">Nested Queries</h2>
140-
<p>Non-correlated subqueries are evaluated once before their parent query. Correlated subqueries are evaluated every time the parent query is evaluated. As an optimization, we can sort the parent tuples by the correlated column and compute the subquery once for every unique value of teh correlated column.</p>
244+
<p>Non-correlated subqueries are evaluated once before their parent query. Correlated subqueries are evaluated every time the parent query is evaluated. As an optimization, we can sort the parent tuples by the correlated column and compute the subquery once for every unique value of the correlated column.</p>
141245
</div>
142246

143247
<script type="text/javascript" src="../js/mathjax_config.js"></script>

0 commit comments

Comments
 (0)