-C Explicit\stypecasts\sto\ssilence\snuisance\scompiler\swarnings.\s\sTicket\s#1398.\s(CVS\s2650)
-D 2005-08-31T13:13:31
+C Updates\sto\sthe\squery\soptimizer\soverview\sdocument.\s(CVS\s2651)
+D 2005-08-31T13:48:35
F Makefile.in 12784cdce5ffc8dfb707300c34e4f1eb3b8a14f1
F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
F www/opcode.tcl 5bd68059416b223515a680d410a9f7cb6736485f
F www/optimizer.tcl d6812a10269bd0d7c488987aac0ad5036cace9dc
F www/optimizing.tcl f0b2538988d1bbad16cbfe63ec6e8f48c9eb04e5
-F www/optoverview.tcl b282361a505bddf85c43217095a66f47dbf6c788
+F www/optoverview.tcl 5ff8a1c38722fa9f5cb3e1b8010f6b91c5a45693
F www/pragma.tcl 44f7b665ca598ad24724f35991653638a36a6e3f
F www/quickstart.tcl 6f6f694b6139be2d967b1492eb9a6bdf7058aa60
F www/speed.tcl 656ed5be8cc9d536353e1a96927b925634a62933
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P ccd12e9e790e271cb1dbbae1c13e9cb980eaf11d
-R 8c9b4e81c8bbdf0ed64b7f65a0971b7c
+P 90712ea7273597214d6c77a01e41f84146d201c8
+R caf39f797300b82be8fdb35ca85651cd
U drh
-Z 3262fbf4b7347c0cb9d90a5c7c2ff379
+Z be0a7dd07de7a11911fd94c99400be61
#
# Run this TCL script to generate HTML for the goals.html file.
#
-set rcsid {$Id: optoverview.tcl,v 1.2 2005/08/31 03:13:12 drh Exp $}
+set rcsid {$Id: optoverview.tcl,v 1.3 2005/08/31 13:48:35 drh Exp $}
source common.tcl
header {The SQLite Query Optimizer Overview}
PARAGRAPH {
This document provides a terse overview of how the query optimizer
- for SQLite works. This is not a tutorial. Some prior knowledge of how
- database engines operate is likely needed in order to fully understand
- this text.
+ for SQLite works. This is not a tutorial. The reader is likely to
+ need some prior knowledge of how database engines operate
+ in order to fully understand this text.
}
HEADING 1 {WHERE clause analysis} where_clause
PARAGRAPH {
The WHERE clause on a query is broken up into "terms" where each term
is separated from the others by an AND operator.
- Parentheses are ignored when dividing the WHERE clause into terms.
}
PARAGRAPH {
- All terms of the WHERE clause are analyzed.
+ All terms of the WHERE clause are analyzed to see if they can be
+ satisfied using indices.
Terms that cannot be satisfied through the use of indices become
tests that are evaluated against each row of the relevant input
tables. No tests are done for terms that are completely satisfied by
}
PARAGRAPH {
- Sometimes the analysis of a term will cause new "virtual" terms to
+ The analysis of a term might cause new "virtual" terms to
be added to the WHERE clause. Virtual terms can be used with
indices to restrict a search. But virtual terms never generate code
that is tested against input rows.
}
PARAGRAPH {
It is not necessary for every column of an index to appear in a
- WHERE clause term in order for that index to be used. In fact, there
- are sometimes advantages if this is not the case.
+ WHERE clause term in order for that index to be used.
But there can not be gaps in the columns of the index that are used.
Thus for the example index above, if there is no WHERE clause term
that constraints column c, then terms that constraint columns a and b can
Similarly, no index column will be used (for indexing purposes)
that is to the right of a
column that is constrained only by inequalities.
- Thus for the index above and WHERE clause like this:
+ For the index above and WHERE clause like this:
}
CODE {
... WHERE a=5 AND b IN (1,2,3) AND c>12 AND d='hello'
evaluate to false. Note that case insensitivity only applies to
latin1 characters - basically the upper and lower case letters of English
in the lower 127 byte codes of ASCII. International character sets
- are always case sensitive in SQLite unless a user-supplied collating
+ are case sensitive in SQLite unless a user-supplied collating
sequence is used. But if you employ a user-supplied collating sequence,
the LIKE optimization describe here will never be taken.
}
Terms of the WHERE clause can be manually disqualified for use with
indices by prepending a unary *+* operator to the column name. The
unary *+* is a no-op and will not slow down the evaluation of the test
- in any way. But it will prevent that term from constraining an index.
+ specified by the term.
+ But it will prevent the term from constraining an index.
So, in the example above, if the query were rewritten as:
}
CODE {
query when possible.
When faced with the choice of using an index to satisfy WHERE clause
constraints or satisfying an ORDER BY clause, SQLite does the same
- work analysis that it normally does when choosing between two indices
- and selects that one that it believes will result in the fastest answer.
- Usually this means satisfying the WHERE clause constraint.
+ work analysis described in section 6.0
+ and chooses the index that it believes will result in the fastest answer.
+
}
HEADING 1 {Subquery flattening} flattening
the form shown above - changing only the name of the table and column.
It is not permissible to add a WHERE clause or do any arithmetic on the
result. The result set must contain a single column.
- And the column in the MIN or MAX function must be an indexed column.
+ The column in the MIN or MAX function must be an indexed column.
}