diff options
author | dan miller | 2007-10-20 02:49:29 +0000 |
---|---|---|
committer | dan miller | 2007-10-20 02:49:29 +0000 |
commit | e36d23a85ebff914d74bb541558c2b6082b78edb (patch) | |
tree | 54b58fdf162e78af64055282a6035c8d2443389d /libraries/sqlite/unix/sqlite-3.5.1/www/optoverview.tcl | |
parent | * Fixed an issue whereby avatar chat distances were being calculated against ... (diff) | |
download | opensim-SC-e36d23a85ebff914d74bb541558c2b6082b78edb.zip opensim-SC-e36d23a85ebff914d74bb541558c2b6082b78edb.tar.gz opensim-SC-e36d23a85ebff914d74bb541558c2b6082b78edb.tar.bz2 opensim-SC-e36d23a85ebff914d74bb541558c2b6082b78edb.tar.xz |
sqlite source (unix build) added to libraries
Diffstat (limited to 'libraries/sqlite/unix/sqlite-3.5.1/www/optoverview.tcl')
-rw-r--r-- | libraries/sqlite/unix/sqlite-3.5.1/www/optoverview.tcl | 516 |
1 files changed, 516 insertions, 0 deletions
diff --git a/libraries/sqlite/unix/sqlite-3.5.1/www/optoverview.tcl b/libraries/sqlite/unix/sqlite-3.5.1/www/optoverview.tcl new file mode 100644 index 0000000..15646e3 --- /dev/null +++ b/libraries/sqlite/unix/sqlite-3.5.1/www/optoverview.tcl | |||
@@ -0,0 +1,516 @@ | |||
1 | # | ||
2 | # Run this TCL script to generate HTML for the goals.html file. | ||
3 | # | ||
4 | set rcsid {$Id: optoverview.tcl,v 1.5 2005/11/24 13:15:34 drh Exp $} | ||
5 | source common.tcl | ||
6 | header {The SQLite Query Optimizer Overview} | ||
7 | |||
8 | proc CODE {text} { | ||
9 | puts "<blockquote><pre>" | ||
10 | puts $text | ||
11 | puts "</pre></blockquote>" | ||
12 | } | ||
13 | proc SYNTAX {text} { | ||
14 | puts "<blockquote><pre>" | ||
15 | set t2 [string map {& & < < > >} $text] | ||
16 | regsub -all "/(\[^\n/\]+)/" $t2 {</b><i>\1</i><b>} t3 | ||
17 | puts "<b>$t3</b>" | ||
18 | puts "</pre></blockquote>" | ||
19 | } | ||
20 | proc IMAGE {name {caption {}}} { | ||
21 | puts "<center><img src=\"$name\">" | ||
22 | if {$caption!=""} { | ||
23 | puts "<br>$caption" | ||
24 | } | ||
25 | puts "</center>" | ||
26 | } | ||
27 | proc PARAGRAPH {text} { | ||
28 | # regsub -all "/(\[a-zA-Z0-9\]+)/" $text {<i>\1</i>} t2 | ||
29 | regsub -all "\\*(\[^\n*\]+)\\*" $text {<tt><b><big>\1</big></b></tt>} t3 | ||
30 | puts "<p>$t3</p>\n" | ||
31 | } | ||
32 | set level(0) 0 | ||
33 | set level(1) 0 | ||
34 | proc HEADING {n name {tag {}}} { | ||
35 | if {$tag!=""} { | ||
36 | puts "<a name=\"$tag\">" | ||
37 | } | ||
38 | global level | ||
39 | incr level($n) | ||
40 | for {set i [expr {$n+1}]} {$i<10} {incr i} { | ||
41 | set level($i) 0 | ||
42 | } | ||
43 | if {$n==0} { | ||
44 | set num {} | ||
45 | } elseif {$n==1} { | ||
46 | set num $level(1).0 | ||
47 | } else { | ||
48 | set num $level(1) | ||
49 | for {set i 2} {$i<=$n} {incr i} { | ||
50 | append num .$level($i) | ||
51 | } | ||
52 | } | ||
53 | incr n 1 | ||
54 | puts "<h$n>$num $name</h$n>" | ||
55 | } | ||
56 | |||
57 | HEADING 0 {The SQLite Query Optimizer Overview} | ||
58 | |||
59 | PARAGRAPH { | ||
60 | This document provides a terse overview of how the query optimizer | ||
61 | for SQLite works. This is not a tutorial. The reader is likely to | ||
62 | need some prior knowledge of how database engines operate | ||
63 | in order to fully understand this text. | ||
64 | } | ||
65 | |||
66 | HEADING 1 {WHERE clause analysis} where_clause | ||
67 | |||
68 | PARAGRAPH { | ||
69 | The WHERE clause on a query is broken up into "terms" where each term | ||
70 | is separated from the others by an AND operator. | ||
71 | } | ||
72 | PARAGRAPH { | ||
73 | All terms of the WHERE clause are analyzed to see if they can be | ||
74 | satisfied using indices. | ||
75 | Terms that cannot be satisfied through the use of indices become | ||
76 | tests that are evaluated against each row of the relevant input | ||
77 | tables. No tests are done for terms that are completely satisfied by | ||
78 | indices. Sometimes | ||
79 | one or more terms will provide hints to indices but still must be | ||
80 | evaluated against each row of the input tables. | ||
81 | } | ||
82 | |||
83 | PARAGRAPH { | ||
84 | The analysis of a term might cause new "virtual" terms to | ||
85 | be added to the WHERE clause. Virtual terms can be used with | ||
86 | indices to restrict a search. But virtual terms never generate code | ||
87 | that is tested against input rows. | ||
88 | } | ||
89 | |||
90 | PARAGRAPH { | ||
91 | To be usable by an index a term must be of one of the following | ||
92 | forms: | ||
93 | } | ||
94 | SYNTAX { | ||
95 | /column/ = /expression/ | ||
96 | /column/ > /expression/ | ||
97 | /column/ >= /expression/ | ||
98 | /column/ < /expression/ | ||
99 | /column/ <= /expression/ | ||
100 | /expression/ = /column/ | ||
101 | /expression/ > /column/ | ||
102 | /expression/ >= /column/ | ||
103 | /expression/ < /column/ | ||
104 | /expression/ <= /column/ | ||
105 | /column/ IN (/expression-list/) | ||
106 | /column/ IN (/subquery/) | ||
107 | } | ||
108 | PARAGRAPH { | ||
109 | If an index is created using a statement like this: | ||
110 | } | ||
111 | CODE { | ||
112 | CREATE INDEX idx_ex1 ON ex1(a,b,c,d,e,...,y,z); | ||
113 | } | ||
114 | PARAGRAPH { | ||
115 | Then the index might be used if the initial columns of the index | ||
116 | (columns a, b, and so forth) appear in WHERE clause terms. | ||
117 | All index columns must be used with | ||
118 | the *=* or *IN* operators except for | ||
119 | the right-most column which can use inequalities. For the right-most | ||
120 | column of an index that is used, there can be up to two inequalities | ||
121 | that must sandwich the allowed values of the column between two extremes. | ||
122 | } | ||
123 | PARAGRAPH { | ||
124 | It is not necessary for every column of an index to appear in a | ||
125 | WHERE clause term in order for that index to be used. | ||
126 | But there can not be gaps in the columns of the index that are used. | ||
127 | Thus for the example index above, if there is no WHERE clause term | ||
128 | that constraints column c, then terms that constraint columns a and b can | ||
129 | be used with the index but not terms that constraint columns d through z. | ||
130 | Similarly, no index column will be used (for indexing purposes) | ||
131 | that is to the right of a | ||
132 | column that is constrained only by inequalities. | ||
133 | For the index above and WHERE clause like this: | ||
134 | } | ||
135 | CODE { | ||
136 | ... WHERE a=5 AND b IN (1,2,3) AND c>12 AND d='hello' | ||
137 | } | ||
138 | PARAGRAPH { | ||
139 | Only columns a, b, and c of the index would be usable. The d column | ||
140 | would not be usable because it occurs to the right of c and c is | ||
141 | constrained only by inequalities. | ||
142 | } | ||
143 | |||
144 | HEADING 1 {The BETWEEN optimization} between_opt | ||
145 | |||
146 | PARAGRAPH { | ||
147 | If a term of the WHERE clause is of the following form: | ||
148 | } | ||
149 | SYNTAX { | ||
150 | /expr1/ BETWEEN /expr2/ AND /expr3/ | ||
151 | } | ||
152 | PARAGRAPH { | ||
153 | Then two virtual terms are added as follows: | ||
154 | } | ||
155 | SYNTAX { | ||
156 | /expr1/ >= /expr2/ AND /expr1/ <= /expr3/ | ||
157 | } | ||
158 | PARAGRAPH { | ||
159 | If both virtual terms end up being used as constraints on an index, | ||
160 | then the original BETWEEN term is omitted and the corresponding test | ||
161 | is not performed on input rows. | ||
162 | Thus if the BETWEEN term ends up being used as an index constraint | ||
163 | no tests are ever performed on that term. | ||
164 | On the other hand, the | ||
165 | virtual terms themselves never causes tests to be performed on | ||
166 | input rows. | ||
167 | Thus if the BETWEEN term is not used as an index constraint and | ||
168 | instead must be used to test input rows, the <i>expr1</i> expression is | ||
169 | only evaluated once. | ||
170 | } | ||
171 | |||
172 | HEADING 1 {The OR optimization} or_opt | ||
173 | |||
174 | PARAGRAPH { | ||
175 | If a term consists of multiple subterms containing a common column | ||
176 | name and separated by OR, like this: | ||
177 | } | ||
178 | SYNTAX { | ||
179 | /column/ = /expr1/ OR /column/ = /expr2/ OR /column/ = /expr3/ OR ... | ||
180 | } | ||
181 | PARAGRAPH { | ||
182 | Then the term is rewritten as follows: | ||
183 | } | ||
184 | SYNTAX { | ||
185 | /column/ IN (/expr1/,/expr2/,/expr3/,/expr4/,...) | ||
186 | } | ||
187 | PARAGRAPH { | ||
188 | The rewritten term then might go on to constraint an index using the | ||
189 | normal rules for *IN* operators. | ||
190 | Note that <i>column</i> must be the same column in every OR-connected subterm, | ||
191 | although the column can occur on either the left or the right side of | ||
192 | the *=* operator. | ||
193 | } | ||
194 | |||
195 | HEADING 1 {The LIKE optimization} like_opt | ||
196 | |||
197 | PARAGRAPH { | ||
198 | Terms that are composed of the LIKE or GLOB operator | ||
199 | can sometimes be used to constrain indices. | ||
200 | There are many conditions on this use: | ||
201 | } | ||
202 | PARAGRAPH { | ||
203 | <ol> | ||
204 | <li>The left-hand side of the LIKE or GLOB operator must be the name | ||
205 | of an indexed column.</li> | ||
206 | <li>The right-hand side of the LIKE or GLOB must be a string literal | ||
207 | that does not begin with a wildcard character.</li> | ||
208 | <li>The ESCAPE clause cannot appear on the LIKE operator.</li> | ||
209 | <li>The build-in functions used to implement LIKE and GLOB must not | ||
210 | have been overloaded using the sqlite3_create_function() API.</li> | ||
211 | <li>For the GLOB operator, the column must use the default BINARY | ||
212 | collating sequence.</li> | ||
213 | <li>For the LIKE operator, if case_sensitive_like mode is enabled then | ||
214 | the column must use the default BINARY collating sequence, or if | ||
215 | case_sensitive_like mode is disabled then the column must use the | ||
216 | built-in NOCASE collating sequence.</li> | ||
217 | </ol> | ||
218 | } | ||
219 | PARAGRAPH { | ||
220 | The LIKE operator has two modes that can be set by a pragma. The | ||
221 | default mode is for LIKE comparisons to be insensitive to differences | ||
222 | of case for latin1 characters. Thus, by default, the following | ||
223 | expression is true: | ||
224 | } | ||
225 | CODE { | ||
226 | 'a' LIKE 'A' | ||
227 | } | ||
228 | PARAGRAPH { | ||
229 | By turned on the case_sensitive_like pragma as follows: | ||
230 | } | ||
231 | CODE { | ||
232 | PRAGMA case_sensitive_like=ON; | ||
233 | } | ||
234 | PARAGRAPH { | ||
235 | Then the LIKE operator pays attention to case and the example above would | ||
236 | evaluate to false. Note that case insensitivity only applies to | ||
237 | latin1 characters - basically the upper and lower case letters of English | ||
238 | in the lower 127 byte codes of ASCII. International character sets | ||
239 | are case sensitive in SQLite unless a user-supplied collating | ||
240 | sequence is used. But if you employ a user-supplied collating sequence, | ||
241 | the LIKE optimization describe here will never be taken. | ||
242 | } | ||
243 | PARAGRAPH { | ||
244 | The LIKE operator is case insensitive by default because this is what | ||
245 | the SQL standard requires. You can change the default behavior at | ||
246 | compile time by using the -DSQLITE_CASE_SENSITIVE_LIKE command-line option | ||
247 | to the compiler. | ||
248 | } | ||
249 | PARAGRAPH { | ||
250 | The LIKE optimization might occur if the column named on the left of the | ||
251 | operator uses the BINARY collating sequence (which is the default) and | ||
252 | case_sensitive_like is turned on. Or the optimization might occur if | ||
253 | the column uses the built-in NOCASE collating sequence and the | ||
254 | case_sensitive_like mode is off. These are the only two combinations | ||
255 | under which LIKE operators will be optimized. If the column on the | ||
256 | right-hand side of the LIKE operator uses any collating sequence other | ||
257 | than the built-in BINARY and NOCASE collating sequences, then no optimizations | ||
258 | will ever be attempted on the LIKE operator. | ||
259 | } | ||
260 | PARAGRAPH { | ||
261 | The GLOB operator is always case sensitive. The column on the left side | ||
262 | of the GLOB operator must always use the built-in BINARY collating sequence | ||
263 | or no attempt will be made to optimize that operator with indices. | ||
264 | } | ||
265 | PARAGRAPH { | ||
266 | The right-hand side of the GLOB or LIKE operator must be a literal string | ||
267 | value that does not begin with a wildcard. If the right-hand side is a | ||
268 | parameter that is bound to a string, then no optimization is attempted. | ||
269 | If the right-hand side begins with a wildcard character then no | ||
270 | optimization is attempted. | ||
271 | } | ||
272 | PARAGRAPH { | ||
273 | Suppose the initial sequence of non-wildcard characters on the right-hand | ||
274 | side of the LIKE or GLOB operator is <i>x</i>. We are using a single | ||
275 | character to denote this non-wildcard prefix but the reader should | ||
276 | understand that the prefix can consist of more than 1 character. | ||
277 | Let <i>y</i> the smallest string that is the same length as /x/ but which | ||
278 | compares greater than <i>x</i>. For example, if <i>x</i> is *hello* then | ||
279 | <i>y</i> would be *hellp*. | ||
280 | The LIKE and GLOB optimizations consist of adding two virtual terms | ||
281 | like this: | ||
282 | } | ||
283 | SYNTAX { | ||
284 | /column/ >= /x/ AND /column/ < /y/ | ||
285 | } | ||
286 | PARAGRAPH { | ||
287 | Under most circumstances, the original LIKE or GLOB operator is still | ||
288 | tested against each input row even if the virtual terms are used to | ||
289 | constrain an index. This is because we do not know what additional | ||
290 | constraints may be imposed by characters to the right | ||
291 | of the <i>x</i> prefix. However, if there is only a single global wildcard | ||
292 | to the right of <i>x</i>, then the original LIKE or GLOB test is disabled. | ||
293 | In other words, if the pattern is like this: | ||
294 | } | ||
295 | SYNTAX { | ||
296 | /column/ LIKE /x/% | ||
297 | /column/ GLOB /x/* | ||
298 | } | ||
299 | PARAGRAPH { | ||
300 | Then the original LIKE or GLOB tests are disabled when the virtual | ||
301 | terms constrain an index because in that case we know that all of the | ||
302 | rows selected by the index will pass the LIKE or GLOB test. | ||
303 | } | ||
304 | |||
305 | HEADING 1 {Joins} joins | ||
306 | |||
307 | PARAGRAPH { | ||
308 | The current implementation of | ||
309 | SQLite uses only loop joins. That is to say, joins are implemented as | ||
310 | nested loops. | ||
311 | } | ||
312 | PARAGRAPH { | ||
313 | The default order of the nested loops in a join is for the left-most | ||
314 | table in the FROM clause to form the outer loop and the right-most | ||
315 | table to form the inner loop. | ||
316 | However, SQLite will nest the loops in a different order if doing so | ||
317 | will help it to select better indices. | ||
318 | } | ||
319 | PARAGRAPH { | ||
320 | Inner joins can be freely reordered. However a left outer join is | ||
321 | neither commutative nor associative and hence will not be reordered. | ||
322 | Inner joins to the left and right of the outer join might be reordered | ||
323 | if the optimizer thinks that is advantageous but the outer joins are | ||
324 | always evaluated in the order in which they occur. | ||
325 | } | ||
326 | PARAGRAPH { | ||
327 | When selecting the order of tables in a join, SQLite uses a greedy | ||
328 | algorithm that runs in polynomial time. | ||
329 | } | ||
330 | PARAGRAPH { | ||
331 | The ON and USING clauses of a join are converted into additional | ||
332 | terms of the WHERE clause prior to WHERE clause analysis described | ||
333 | above in paragraph 1.0. Thus | ||
334 | with SQLite, there is no advantage to use the newer SQL92 join syntax | ||
335 | over the older SQL89 comma-join syntax. They both end up accomplishing | ||
336 | exactly the same thing. | ||
337 | } | ||
338 | PARAGRAPH { | ||
339 | Join reordering is automatic and usually works well enough that | ||
340 | programmer do not have to think about it. But occasionally some | ||
341 | hints from the programmer are needed. For a description of when | ||
342 | hints might be necessary and how to provide those hints, see the | ||
343 | <a href="http://www.sqlite.org/cvstrac/wiki?p=QueryPlans">QueryPlans</a> | ||
344 | page in the Wiki. | ||
345 | } | ||
346 | |||
347 | HEADING 1 {Choosing between multiple indices} multi_index | ||
348 | |||
349 | PARAGRAPH { | ||
350 | Each table in the FROM clause of a query can use at most one index, | ||
351 | and SQLite strives to use at least one index on each table. Sometimes, | ||
352 | two or more indices might be candidates for use on a single table. | ||
353 | For example: | ||
354 | } | ||
355 | CODE { | ||
356 | CREATE TABLE ex2(x,y,z); | ||
357 | CREATE INDEX ex2i1 ON ex2(x); | ||
358 | CREATE INDEX ex2i2 ON ex2(y); | ||
359 | SELECT z FROM ex2 WHERE x=5 AND y=6; | ||
360 | } | ||
361 | PARAGRAPH { | ||
362 | For the SELECT statement above, the optimizer can use the ex2i1 index | ||
363 | to lookup rows of ex2 that contain x=5 and then test each row against | ||
364 | the y=6 term. Or it can use the ex2i2 index to lookup rows | ||
365 | of ex2 that contain y=6 then test each of those rows against the | ||
366 | x=5 term. | ||
367 | } | ||
368 | PARAGRAPH { | ||
369 | When faced with a choice of two or more indices, SQLite tries to estimate | ||
370 | the total amount of work needed to perform the query using each option. | ||
371 | It then selects the option that gives the least estimated work. | ||
372 | } | ||
373 | PARAGRAPH { | ||
374 | To help the optimizer get a more accurate estimate of the work involved | ||
375 | in using various indices, the user may optional run the ANALYZE command. | ||
376 | The ANALYZE command scans all indices of database where there might | ||
377 | be a choice between two or more indices and gathers statistics on the | ||
378 | selectiveness of those indices. The results of this scan are stored | ||
379 | in the sqlite_stat1 table. | ||
380 | The contents of the sqlite_stat1 table are not updated as the database | ||
381 | changes so after making significant changes it might be prudent to | ||
382 | rerun ANALYZE. | ||
383 | The results of an ANALYZE command are only available to database connections | ||
384 | that are opened after the ANALYZE command completes. | ||
385 | } | ||
386 | PARAGRAPH { | ||
387 | Once created, the sqlite_stat1 table cannot be dropped. But its | ||
388 | content can be viewed, modified, or erased. Erasing the entire content | ||
389 | of the sqlite_stat1 table has the effect of undoing the ANALYZE command. | ||
390 | Changing the content of the sqlite_stat1 table can get the optimizer | ||
391 | deeply confused and cause it to make silly index choices. Making | ||
392 | updates to the sqlite_stat1 table (except by running ANALYZE) is | ||
393 | not recommended. | ||
394 | } | ||
395 | PARAGRAPH { | ||
396 | Terms of the WHERE clause can be manually disqualified for use with | ||
397 | indices by prepending a unary *+* operator to the column name. The | ||
398 | unary *+* is a no-op and will not slow down the evaluation of the test | ||
399 | specified by the term. | ||
400 | But it will prevent the term from constraining an index. | ||
401 | So, in the example above, if the query were rewritten as: | ||
402 | } | ||
403 | CODE { | ||
404 | SELECT z FROM ex2 WHERE +x=5 AND y=6; | ||
405 | } | ||
406 | PARAGRAPH { | ||
407 | The *+* operator on the *x* column would prevent that term from | ||
408 | constraining an index. This would force the use of the ex2i2 index. | ||
409 | } | ||
410 | |||
411 | HEADING 1 {Avoidance of table lookups} index_only | ||
412 | |||
413 | PARAGRAPH { | ||
414 | When doing an indexed lookup of a row, the usual procedure is to | ||
415 | do a binary search on the index to find the index entry, then extract | ||
416 | the rowid from the index and use that rowid to do a binary search on | ||
417 | the original table. Thus a typical indexed lookup involves two | ||
418 | binary searches. | ||
419 | If, however, all columns that were to be fetched from the table are | ||
420 | already available in the index itself, SQLite will use the values | ||
421 | contained in the index and will never look up the original table | ||
422 | row. This saves one binary search for each row and can make many | ||
423 | queries run twice as fast. | ||
424 | } | ||
425 | |||
426 | HEADING 1 {ORDER BY optimizations} order_by | ||
427 | |||
428 | PARAGRAPH { | ||
429 | SQLite attempts to use an index to satisfy the ORDER BY clause of a | ||
430 | query when possible. | ||
431 | When faced with the choice of using an index to satisfy WHERE clause | ||
432 | constraints or satisfying an ORDER BY clause, SQLite does the same | ||
433 | work analysis described in section 6.0 | ||
434 | and chooses the index that it believes will result in the fastest answer. | ||
435 | |||
436 | } | ||
437 | |||
438 | HEADING 1 {Subquery flattening} flattening | ||
439 | |||
440 | PARAGRAPH { | ||
441 | When a subquery occurs in the FROM clause of a SELECT, the default | ||
442 | behavior is to evaluate the subquery into a transient table, then run | ||
443 | the outer SELECT against the transient table. | ||
444 | This is problematic since the transient table will not have any indices | ||
445 | and the outer query (which is likely a join) will be forced to do a | ||
446 | full table scan on the transient table. | ||
447 | } | ||
448 | PARAGRAPH { | ||
449 | To overcome this problem, SQLite attempts to flatten subqueries in | ||
450 | the FROM clause of a SELECT. | ||
451 | This involves inserting the FROM clause of the subquery into the | ||
452 | FROM clause of the outer query and rewriting expressions in | ||
453 | the outer query that refer to the result set of the subquery. | ||
454 | For example: | ||
455 | } | ||
456 | CODE { | ||
457 | SELECT a FROM (SELECT x+y AS a FROM t1 WHERE z<100) WHERE a>5 | ||
458 | } | ||
459 | PARAGRAPH { | ||
460 | Would be rewritten using query flattening as: | ||
461 | } | ||
462 | CODE { | ||
463 | SELECT x+y AS a FROM t1 WHERE z<100 AND a>5 | ||
464 | } | ||
465 | PARAGRAPH { | ||
466 | There is a long list of conditions that must all be met in order for | ||
467 | query flattening to occur. | ||
468 | } | ||
469 | PARAGRAPH { | ||
470 | <ol> | ||
471 | <li> The subquery and the outer query do not both use aggregates.</li> | ||
472 | <li> The subquery is not an aggregate or the outer query is not a join. </li> | ||
473 | <li> The subquery is not the right operand of a left outer join, or | ||
474 | the subquery is not itself a join. </li> | ||
475 | <li> The subquery is not DISTINCT or the outer query is not a join. </li> | ||
476 | <li> The subquery is not DISTINCT or the outer query does not use | ||
477 | aggregates. </li> | ||
478 | <li> The subquery does not use aggregates or the outer query is not | ||
479 | DISTINCT. </li> | ||
480 | <li> The subquery has a FROM clause. </li> | ||
481 | <li> The subquery does not use LIMIT or the outer query is not a join. </li> | ||
482 | <li> The subquery does not use LIMIT or the outer query does not use | ||
483 | aggregates. </li> | ||
484 | <li> The subquery does not use aggregates or the outer query does not | ||
485 | use LIMIT. </li> | ||
486 | <li> The subquery and the outer query do not both have ORDER BY clauses.</li> | ||
487 | <li> The subquery is not the right term of a LEFT OUTER JOIN or the | ||
488 | subquery has no WHERE clause. </li> | ||
489 | </ol> | ||
490 | } | ||
491 | PARAGRAPH { | ||
492 | The proof that query flattening may safely occur if all of the the | ||
493 | above conditions are met is left as an exercise to the reader. | ||
494 | } | ||
495 | PARAGRAPH { | ||
496 | Query flattening is an important optimization when views are used as | ||
497 | each use of a view is translated into a subquery. | ||
498 | } | ||
499 | |||
500 | HEADING 1 {The MIN/MAX optimization} minmax | ||
501 | |||
502 | PARAGRAPH { | ||
503 | Queries of the following forms will be optimized to run in logarithmic | ||
504 | time assuming appropriate indices exist: | ||
505 | } | ||
506 | CODE { | ||
507 | SELECT MIN(x) FROM table; | ||
508 | SELECT MAX(x) FROM table; | ||
509 | } | ||
510 | PARAGRAPH { | ||
511 | In order for these optimizations to occur, they must appear in exactly | ||
512 | the form shown above - changing only the name of the table and column. | ||
513 | It is not permissible to add a WHERE clause or do any arithmetic on the | ||
514 | result. The result set must contain a single column. | ||
515 | The column in the MIN or MAX function must be an indexed column. | ||
516 | } | ||