@polycode-projects/the-mechanical-code-talker 2.3.0 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/corpus/LICENSES.json +19 -4
  2. package/corpus/README.md +48 -0
  3. package/corpus/generated/README.md +24 -9
  4. package/corpus/generated/ace-surface-variants.jsonl +4 -1
  5. package/corpus/generated/manifest.json +4 -4
  6. package/corpus/prose/manifest.json +512 -0
  7. package/corpus/prose/sqlite/LICENSE-NOTICE +53 -0
  8. package/corpus/prose/sqlite/arch.txt +213 -0
  9. package/corpus/prose/sqlite/atomiccommit.txt +1117 -0
  10. package/corpus/prose/sqlite/faq.txt +473 -0
  11. package/corpus/prose/sqlite/fileformat.txt +1589 -0
  12. package/corpus/prose/sqlite/lang_createtable.txt +1339 -0
  13. package/corpus/prose/sqlite/lang_insert.txt +580 -0
  14. package/corpus/prose/sqlite/lang_select.txt +3293 -0
  15. package/corpus/prose/sqlite/optoverview.txt +908 -0
  16. package/corpus/prose/sqlite/queryplanner.txt +447 -0
  17. package/corpus/prose/sqlite/transactional.txt +41 -0
  18. package/corpus/prose/sqlite/wal.txt +567 -0
  19. package/corpus/prose/sqlite/whentouse.txt +300 -0
  20. package/corpus/prose/wikipedia/Apple.txt +4 -0
  21. package/corpus/prose/wikipedia/Attempto_Controlled_English.txt +169 -0
  22. package/corpus/prose/wikipedia/Automated_planning_and_scheduling.txt +67 -0
  23. package/corpus/prose/wikipedia/Bee.txt +7 -0
  24. package/corpus/prose/wikipedia/Bird.txt +8 -0
  25. package/corpus/prose/wikipedia/Bone.txt +4 -0
  26. package/corpus/prose/wikipedia/Book.txt +7 -0
  27. package/corpus/prose/wikipedia/Bread.txt +6 -0
  28. package/corpus/prose/wikipedia/Butterfly.txt +6 -0
  29. package/corpus/prose/wikipedia/Car.txt +1 -0
  30. package/corpus/prose/wikipedia/Cat.txt +1 -0
  31. package/corpus/prose/wikipedia/Child.txt +3 -0
  32. package/corpus/prose/wikipedia/City.txt +2 -0
  33. package/corpus/prose/wikipedia/Clock.txt +2 -0
  34. package/corpus/prose/wikipedia/Cooking.txt +1 -0
  35. package/corpus/prose/wikipedia/Description_logic.txt +660 -0
  36. package/corpus/prose/wikipedia/Doctor.txt +6 -0
  37. package/corpus/prose/wikipedia/Dog.txt +4 -0
  38. package/corpus/prose/wikipedia/Eagle.txt +4 -0
  39. package/corpus/prose/wikipedia/Emotion.txt +9 -0
  40. package/corpus/prose/wikipedia/Eye.txt +5 -0
  41. package/corpus/prose/wikipedia/Family.txt +3 -0
  42. package/corpus/prose/wikipedia/Farm.txt +4 -0
  43. package/corpus/prose/wikipedia/Fear.txt +4 -0
  44. package/corpus/prose/wikipedia/First-order_logic.txt +1518 -0
  45. package/corpus/prose/wikipedia/Fish.txt +10 -0
  46. package/corpus/prose/wikipedia/Flower.txt +3 -0
  47. package/corpus/prose/wikipedia/Food.txt +10 -0
  48. package/corpus/prose/wikipedia/Grass.txt +9 -0
  49. package/corpus/prose/wikipedia/Hand.txt +2 -0
  50. package/corpus/prose/wikipedia/Happiness.txt +3 -0
  51. package/corpus/prose/wikipedia/Heart.txt +4 -0
  52. package/corpus/prose/wikipedia/Horse.txt +4 -0
  53. package/corpus/prose/wikipedia/House.txt +6 -0
  54. package/corpus/prose/wikipedia/Human.txt +4 -0
  55. package/corpus/prose/wikipedia/Insect.txt +6 -0
  56. package/corpus/prose/wikipedia/Interactive_fiction.txt +112 -0
  57. package/corpus/prose/wikipedia/Knowledge.txt +5 -0
  58. package/corpus/prose/wikipedia/Knowledge_representation_and_reasoning.txt +87 -0
  59. package/corpus/prose/wikipedia/LICENSE-NOTICE +94 -0
  60. package/corpus/prose/wikipedia/Language.txt +10 -0
  61. package/corpus/prose/wikipedia/Learning.txt +4 -0
  62. package/corpus/prose/wikipedia/Mammal.txt +3 -0
  63. package/corpus/prose/wikipedia/Memory.txt +5 -0
  64. package/corpus/prose/wikipedia/Milk.txt +1 -0
  65. package/corpus/prose/wikipedia/Mountain.txt +1 -0
  66. package/corpus/prose/wikipedia/Natural_language_processing.txt +211 -0
  67. package/corpus/prose/wikipedia/Ostrich.txt +2 -0
  68. package/corpus/prose/wikipedia/Owl.txt +2 -0
  69. package/corpus/prose/wikipedia/Penguin.txt +2 -0
  70. package/corpus/prose/wikipedia/Plant.txt +5 -0
  71. package/corpus/prose/wikipedia/Rain.txt +1 -0
  72. package/corpus/prose/wikipedia/Resource_Description_Framework.txt +184 -0
  73. package/corpus/prose/wikipedia/River.txt +1 -0
  74. package/corpus/prose/wikipedia/School.txt +8 -0
  75. package/corpus/prose/wikipedia/Sea.txt +1 -0
  76. package/corpus/prose/wikipedia/Semantic_Web.txt +114 -0
  77. package/corpus/prose/wikipedia/Semantic_reasoner.txt +29 -0
  78. package/corpus/prose/wikipedia/Snow.txt +5 -0
  79. package/corpus/prose/wikipedia/Sun.txt +5 -0
  80. package/corpus/prose/wikipedia/Teacher.txt +4 -0
  81. package/corpus/prose/wikipedia/Team.txt +3 -0
  82. package/corpus/prose/wikipedia/Text-based_game.txt +17 -0
  83. package/corpus/prose/wikipedia/Tool.txt +4 -0
  84. package/corpus/prose/wikipedia/Tree.txt +7 -0
  85. package/corpus/prose/wikipedia/Weather.txt +4 -0
  86. package/corpus/prose/wikipedia/Web_Ontology_Language.txt +133 -0
  87. package/corpus/prose/wikipedia/Wind.txt +8 -0
  88. package/corpus/prose/wikipedia/Writing.txt +5 -0
  89. package/package.json +2 -1
@@ -0,0 +1,908 @@
1
+ The SQLite Query Optimizer Overview
2
+ Small. Fast. Reliable.
3
+ Choose any three.
4
+ Home
5
+ Menu
6
+ About
7
+ Documentation
8
+ Download
9
+ License
10
+ Support
11
+ Purchase
12
+ Search
13
+ About
14
+ Documentation
15
+ Download
16
+ Support
17
+ Purchase
18
+ Search Documentation
19
+ Search Changelog
20
+ The SQLite Query Optimizer Overview
21
+ Table Of Contents
22
+ 1. Introduction
23
+ 2. WHERE Clause Analysis
24
+ 2.1. Index Term Usage Examples
25
+ 3. The BETWEEN Optimization
26
+ 4. OR Optimizations
27
+ 4.1. Converting OR-connected constraint into an IN operator
28
+ 4.2. Evaluating OR constraints separately and taking the UNION of the result
29
+ 5. The LIKE Optimization
30
+ 6. The Skip-Scan Optimization
31
+ 7. Joins
32
+ 7.1. Manual Control Of Join Order
33
+ 7.1.1. Manual Control Of Query Plans Using SQLITE_STAT Tables
34
+ 7.1.2. Manual Control of Query Plans using CROSS JOIN
35
+ 8. Choosing Between Multiple Indexes
36
+ 8.1. Disqualifying WHERE Clause Terms using Unary-"+"
37
+ 8.2. Range Queries
38
+ 9. Covering Indexes
39
+ 10. ORDER BY Optimizations
40
+ 10.1. Partial ORDER BY via Index
41
+ 11. Subquery Flattening
42
+ 12. Subquery Co-routines
43
+ 12.1. Using Co-routines to Defer Work until after the Sorting
44
+ 13. The MIN/MAX Optimization
45
+ 14. Automatic Query-Time Indexes
46
+ 14.1. Hash Joins
47
+ 15. The Predicate Push-Down Optimization
48
+ 16. The OUTER JOIN Strength Reduction Optimization
49
+ 17. The Omit OUTER JOIN Optimization
50
+ 18. The Constant Propagation Optimization
51
+ 1. Introduction
52
+ This document provides an overview of how the query planner and optimizer
53
+ for SQLite works.
54
+ Given a single SQL statement, there might be dozens, hundreds, or even
55
+ thousands of ways to implement that statement, depending on the complexity
56
+ of the statement itself and of the underlying database schema. The
57
+ task of the query planner is to select the algorithm that minimizes
58
+ disk I/O and CPU overhead.
59
+ Additional background information is available in the
60
+ indexing tutorial document.
61
+ The Next Generation Query Planner document provides more detail on
62
+ how the join order is chosen.
63
+ 2. WHERE Clause Analysis
64
+ Prior to analysis, the following transformations are made
65
+ to shift all join constraints into the WHERE clause:
66
+ All NATURAL joins are converted into joins with a USING clause.
67
+ All USING clauses (including ones created by the previous step)
68
+ are converted into equivalent ON clauses.
69
+ All ON clauses (include ones created by the previous step)
70
+ are added as new conjuncts (AND-connected terms) in the WHERE clause.
71
+ SQLite makes no distinction between join constraints that occur in the
72
+ WHERE clause and constraints in the ON clause of an inner join, since that
73
+ distinction does not affect the outcome. However, there is
74
+ a difference between ON clause constraints and WHERE clause constraints for
75
+ outer joins. Therefore, when SQLite moves an ON clause constraint from an
76
+ outer join over to the WHERE clause it adds special tags to the Abstract
77
+ Syntax Tree (AST) to indicate that the constraint came from an outer join
78
+ and from which outer join it came. There is no way to add those tags in
79
+ pure SQL text. Hence, the SQL input must use ON clauses on outer joins.
80
+ But in the internal AST, all constraints are part of the WHERE clause,
81
+ because having everything in one place simplifies processing.
82
+ After all constraints have been shifted into the WHERE clause,
83
+ The WHERE clause is broken up into conjuncts (hereafter called
84
+ "terms"). In other words, the WHERE clause is broken up into pieces
85
+ separated from the others by an AND operator.
86
+ If the WHERE clause is composed of constraints separated by the OR
87
+ operator (disjuncts) then the entire clause is considered to be a single "term"
88
+ to which the OR-clause optimization is applied.
89
+ All terms of the WHERE clause are analyzed to see if they can be
90
+ satisfied using indexes.
91
+ To be usable by an index a term must usually be of one of the following
92
+ forms:
93
+ If an index is created using a statement like this:
94
+ Then the index might be used if the initial columns of the index
95
+ (columns a, b, and so forth) appear in WHERE clause terms.
96
+ The initial columns of the index must be used with
97
+ the = or IN or IS operators.
98
+ The right-most column that is used can employ inequalities.
99
+ For the right-most
100
+ column of an index that is used, there can be up to two inequalities
101
+ that must sandwich the allowed values of the column between two extremes.
102
+ It is not necessary for every column of an index to appear in a
103
+ WHERE clause term in order for that index to be used.
104
+ However, there cannot be gaps in the columns of the index that are used.
105
+ Thus for the example index above, if there is no WHERE clause term
106
+ that constrains column c, then terms that constrain columns a and b can
107
+ be used with the index but not terms that constrain columns d through z.
108
+ Similarly, index columns will not normally be used (for indexing purposes)
109
+ if they are to the right of a
110
+ column that is constrained only by inequalities.
111
+ (See the skip-scan optimization below for the exception.)
112
+ In the case of indexes on expressions , whenever the word "column" is
113
+ used in the foregoing text, one can substitute "indexed expression"
114
+ (meaning a copy of the expression that appears in the CREATE INDEX
115
+ statement) and everything will work the same.
116
+ 2.1. Index Term Usage Examples
117
+ For the index above and WHERE clause like this:
118
+ The first four columns a, b, c, and d of the index would be usable since
119
+ those four columns form a prefix of the index and are all bound by
120
+ equality constraints.
121
+ For the index above and WHERE clause like this:
122
+ Only columns a, b, and c of the index would be usable. The d column
123
+ would not be usable because it occurs to the right of c and c is
124
+ constrained only by inequalities.
125
+ For the index above and WHERE clause like this:
126
+ Only columns a and b of the index would be usable. The d column
127
+ would not be usable because column c is not constrained and there can
128
+ be no gaps in the set of columns that usable by the index.
129
+ For the index above and WHERE clause like this:
130
+ The index is not usable at all because the left-most column of the
131
+ index (column "a") is not constrained. Assuming there are no other
132
+ indexes, the query above would result in a full table scan.
133
+ For the index above and WHERE clause like this:
134
+ The index is not usable because the WHERE clause terms are connected
135
+ by OR instead of AND. This query would result in a full table scan.
136
+ However, if three additional indexes are added that contain columns
137
+ b, c, and d as their left-most columns, then the
138
+ OR-clause optimization might apply.
139
+ 3. The BETWEEN Optimization
140
+ If a term of the WHERE clause is of the following form:
141
+ Then two "virtual" terms are added as follows:
142
+ Virtual terms are used for analysis only and do not cause any byte-code
143
+ to be generated.
144
+ If both virtual terms end up being used as constraints on an index,
145
+ then the original BETWEEN term is omitted and the corresponding test
146
+ is not performed on input rows.
147
+ Thus if the BETWEEN term ends up being used as an index constraint
148
+ no tests are ever performed on that term.
149
+ On the other hand, the
150
+ virtual terms themselves never causes tests to be performed on
151
+ input rows.
152
+ Thus if the BETWEEN term is not used as an index constraint and
153
+ instead must be used to test input rows, the expr1 expression is
154
+ only evaluated once.
155
+ 4. OR Optimizations
156
+ WHERE clause constraints that are connected by OR instead of AND can
157
+ be handled in two different ways.
158
+ 4.1. Converting OR-connected constraint into an IN operator
159
+ If a term consists of multiple subterms containing a common column
160
+ name and separated by OR, like this:
161
+ Then that term is rewritten as follows:
162
+ The rewritten term then might go on to constrain an index using the
163
+ normal rules for IN operators. Note that column must be
164
+ the same column in every OR-connected subterm,
165
+ although the column can occur on either the left or the right side of
166
+ the = operator.
167
+ 4.2. Evaluating OR constraints separately and taking the UNION of the result
168
+ If and only if the previously described conversion of OR to an IN operator
169
+ does not work, the second OR-clause optimization is attempted.
170
+ Suppose the OR clause consists of multiple subterms as follows:
171
+ Individual subterms might be a single comparison expression like
172
+ a=5 or x>y or they can be
173
+ LIKE or BETWEEN expressions, or a subterm
174
+ can be a parenthesized list of AND-connected sub-subterms.
175
+ Each subterm is analyzed as if it were itself the entire WHERE clause
176
+ in order to see if the subterm is indexable by itself.
177
+ If every subterm of an OR clause is separately indexable
178
+ then the OR clause might be coded such that a separate index is used
179
+ to evaluate each term of the OR clause. One way to think about how
180
+ SQLite uses separate indexes for each OR clause term is to imagine
181
+ that the WHERE clause where rewritten as follows:
182
+ The rewritten expression above is conceptual; WHERE clauses containing
183
+ OR are not really rewritten this way.
184
+ The actual implementation of the OR clause uses a mechanism that is
185
+ more efficient and that works even for WITHOUT ROWID tables or
186
+ tables in which the "rowid" is inaccessible. Nevertheless,
187
+ the essence of the implementation is captured by the statement
188
+ above: Separate indexes are used to find candidate result rows
189
+ from each OR clause term and the final result is the union of
190
+ those rows.
191
+ Note that in most cases, SQLite will only use a single index for each
192
+ table in the FROM clause of a query. The second OR-clause optimization
193
+ described here is the exception to that rule. With an OR-clause,
194
+ a different index might be used for each subterm in the OR-clause.
195
+ For any given query, the fact that the OR-clause optimization described
196
+ here can be used does not guarantee that it will be used.
197
+ SQLite uses a cost-based query planner that estimates the CPU and
198
+ disk I/O costs of various competing query plans and chooses the plan
199
+ that it thinks will be the fastest. If there are many OR terms in
200
+ the WHERE clause or if some of the indexes on individual OR-clause
201
+ subterms are not very selective, then SQLite might decide that it is
202
+ faster to use a different query algorithm, or even a full-table scan.
203
+ Application developers can use the
204
+ EXPLAIN QUERY PLAN prefix on a statement to get a
205
+ high-level overview of the chosen query strategy.
206
+ 5. The LIKE Optimization
207
+ A WHERE-clause term that uses the LIKE or GLOB operator
208
+ can sometimes be used with an index to do a range search,
209
+ almost as if the LIKE or GLOB were an alternative to a BETWEEN
210
+ operator.
211
+ There are many conditions on this optimization:
212
+ The right-hand side of the LIKE or GLOB must be either a string literal
213
+ or a parameter bound to a string literal
214
+ that does not begin with a wildcard character.
215
+ It must not be possible to make the LIKE or GLOB operator true by
216
+ having a numeric value (instead of a string or blob) on the
217
+ left-hand side. This means that either:
218
+ the left-hand side of the LIKE or GLOB operator is the name
219
+ of an indexed column with TEXT affinity , or
220
+ the right-hand side pattern argument does not begin with a
221
+ minus sign ("-") or a digit.
222
+ This constraint arises from the fact that numbers do not sort in
223
+ lexicographical order. For example: 9<10 but '9'>'10'.
224
+ The built-in functions used to implement LIKE and GLOB must not
225
+ have been overloaded using the sqlite3_create_function() API.
226
+ For the GLOB operator, the column must be indexed using the
227
+ built-in BINARY collating sequence.
228
+ For the LIKE operator, if case_sensitive_like mode is enabled then
229
+ the column must be indexed using the built-in BINARY collating sequence,
230
+ or if case_sensitive_like mode is disabled then the column must be
231
+ indexed using the built-in NOCASE collating sequence.
232
+ If the ESCAPE option is used, the ESCAPE character must be ASCII,
233
+ or a single-byte character in UTF-8.
234
+ The LIKE operator has two modes that can be set by a
235
+ pragma . The
236
+ default mode is for LIKE comparisons to be insensitive to differences
237
+ of case for latin1 characters. Thus, by default, the following
238
+ expression is true:
239
+ If the case_sensitive_like pragma is enabled as follows:
240
+ Then the LIKE operator pays attention to case and the example above would
241
+ evaluate to false. Note that case insensitivity only applies to
242
+ latin1 characters - basically the upper and lower case letters of English
243
+ in the lower 127 byte codes of ASCII. International character sets
244
+ are case sensitive in SQLite unless an application-defined
245
+ collating sequence and like() SQL function are provided that
246
+ take non-ASCII characters into account.
247
+ If an application-defined collating sequence and/or like() SQL
248
+ function are provided, the LIKE optimization described here will never
249
+ be taken.
250
+ The LIKE operator is case insensitive by default because this is what
251
+ the SQL standard requires. You can change the default behavior at
252
+ compile time by using the SQLITE_CASE_SENSITIVE_LIKE command-line option
253
+ to the compiler.
254
+ The LIKE optimization might occur if the column named on the left of the
255
+ operator is indexed using the built-in BINARY collating sequence and
256
+ case_sensitive_like is turned on. Or the optimization might occur if
257
+ the column is indexed using the built-in NOCASE collating sequence and the
258
+ case_sensitive_like mode is off. These are the only two combinations
259
+ under which LIKE operators will be optimized.
260
+ The GLOB operator is always case sensitive. The column on the left side
261
+ of the GLOB operator must always use the built-in BINARY collating sequence
262
+ or no attempt will be made to optimize that operator with indexes.
263
+ The LIKE optimization will only be attempted if
264
+ the right-hand side of the GLOB or LIKE operator is either a
265
+ literal string or a parameter that has been bound
266
+ to a string literal. The string literal must not
267
+ begin with a wildcard; if the right-hand side begins with a wildcard
268
+ character then this optimization is not attempted. If the right-hand side
269
+ is a parameter that is bound to a string, then this optimization is
270
+ only attempted if the prepared statement containing the expression
271
+ was compiled with sqlite3_prepare_v2() or sqlite3_prepare16_v2() .
272
+ The LIKE optimization is not attempted if the
273
+ right-hand side is a parameter and the statement was prepared using
274
+ sqlite3_prepare() or sqlite3_prepare16() .
275
+ Suppose the initial sequence of non-wildcard characters on the right-hand
276
+ side of the LIKE or GLOB operator is x . We are using a single
277
+ character to denote this non-wildcard prefix but the reader should
278
+ understand that the prefix can consist of more than 1 character.
279
+ Let y be the smallest string that is the same length as /x/ but which
280
+ compares greater than x . For example, if x is
281
+ 'hello' then
282
+ y would be 'hellp' .
283
+ The LIKE and GLOB optimizations consist of adding two virtual terms
284
+ like this:
285
+ Under most circumstances, the original LIKE or GLOB operator is still
286
+ tested against each input row even if the virtual terms are used to
287
+ constrain an index. This is because we do not know what additional
288
+ constraints may be imposed by characters to the right
289
+ of the x prefix. However, if there is only a single
290
+ global wildcard to the right of x , then the original LIKE or
291
+ GLOB test is disabled.
292
+ In other words, if the pattern is like this:
293
+ then the original LIKE or GLOB tests are disabled when the virtual
294
+ terms constrain an index because in that case we know that all of the
295
+ rows selected by the index will pass the LIKE or GLOB test.
296
+ Note that when the right-hand side of a LIKE or GLOB operator is
297
+ a parameter and the statement is prepared using sqlite3_prepare_v2()
298
+ or sqlite3_prepare16_v2() then the statement is automatically reparsed
299
+ and recompiled on the first sqlite3_step() call of each run if the binding
300
+ to the right-hand side parameter has changed since the previous run.
301
+ This reparse and recompile is essentially the same action that occurs
302
+ following a schema change. The recompile is necessary so that the query
303
+ planner can examine the new value bound to the right-hand side of the
304
+ LIKE or GLOB operator and determine whether or not to employ the
305
+ optimization described above.
306
+ 6. The Skip-Scan Optimization
307
+ The general rule is that indexes are only useful if there are
308
+ WHERE-clause constraints on the left-most columns of the index.
309
+ However, in some cases,
310
+ SQLite is able to use an index even if the first few columns of
311
+ the index are omitted from the WHERE clause but later columns
312
+ are included.
313
+ Consider a table such as the following:
314
+ The people table has one entry for each person in a large
315
+ organization. Each person is either a "student" or a "teacher",
316
+ as determined by the "role" field. The table also records the height in
317
+ centimeters of each person. The role and height are indexed.
318
+ Notice that the left-most column of the index is not very
319
+ selective - it only contains two possible values.
320
+ Now consider a query to find the names of everyone in the
321
+ organization that is 180cm tall or taller:
322
+ Because the left-most column of the index does not appear in the
323
+ WHERE clause of the query, one is tempted to conclude that the
324
+ index is not usable here. However, SQLite is able to use the index.
325
+ Conceptually, SQLite uses the index as if the query were more
326
+ like the following:
327
+ Or this:
328
+ The alternative query formulations shown above are conceptual only.
329
+ SQLite does not really transform the query.
330
+ The actual query plan is like this:
331
+ SQLite locates the first possible value for "role", which it
332
+ can do by rewinding the "people_idx1" index to the beginning and reading
333
+ the first record. SQLite stores this first "role" value in an
334
+ internal variable that we will here call "$role". Then SQLite
335
+ runs a query like: "SELECT name FROM people WHERE role=$role AND height>=180".
336
+ This query has an equality constraint on the left-most column of the
337
+ index and so the index can be used to resolve that query. Once
338
+ that query is finished, SQLite then uses the "people_idx1" index to
339
+ locate the next value of the "role" column, using code that is logically
340
+ similar to "SELECT role FROM people WHERE role>$role LIMIT 1".
341
+ This new "role" value overwrites the $role variable, and the process
342
+ repeats until all possible values for "role" have been examined.
343
+ We call this kind of index usage a "skip-scan" because the database
344
+ engine is basically doing a full scan of the index but it optimizes the
345
+ scan (making it less than "full") by occasionally skipping ahead to the
346
+ next candidate value.
347
+ SQLite might use a skip-scan on an index if it knows that the first
348
+ one or more columns contain many duplication values.
349
+ If there are too few duplicates
350
+ in the left-most columns of the index, then it would
351
+ be faster to simply step ahead to the next value, and thus do
352
+ a full table scan, than to do a binary search on an index to locate
353
+ the next left-column value.
354
+ The only way that SQLite can know that there are many duplicates
355
+ in the left-most columns of an index
356
+ is if the ANALYZE command has been run
357
+ on the database.
358
+ Without the results of ANALYZE, SQLite has to guess at the "shape" of
359
+ the data in the table, and the default guess is that there are an average
360
+ of 10 duplicates for every value in the left-most column of the index.
361
+ Skip-scan only becomes profitable (it only gets to be faster than
362
+ a full table scan) when the number of duplicates is about 18 or more.
363
+ Hence, a skip-scan is never used on a database that has not been analyzed.
364
+ 7. Joins
365
+ SQLite implements joins as nested loops.
366
+ The default order of the nested loops in a join is for the left-most
367
+ table in the FROM clause to form the outer loop and the right-most
368
+ table to form the inner loop.
369
+ However, SQLite will nest the loops in a different order if doing so
370
+ will help it to select better indexes.
371
+ Inner joins can be freely reordered. However outer joins are
372
+ neither commutative nor associative and hence will not be reordered.
373
+ Inner joins to the left and right of an outer join might be reordered
374
+ if the optimizer thinks that is advantageous but outer joins are
375
+ always evaluated in the order in which they occur.
376
+ SQLite treats the CROSS JOIN operator specially .
377
+ The CROSS JOIN operator is commutative, in theory. However, SQLite chooses to
378
+ never reorder tables in a CROSS JOIN. This provides a mechanism
379
+ by which the programmer can force SQLite to choose a particular loop nesting
380
+ order.
381
+ When selecting the order of tables in a join, SQLite uses an efficient
382
+ polynomial-time algorithm graph algorithm described in
383
+ the Next Generation Query Planner document. Because of this,
384
+ SQLite is able to plan queries with 50- or 60-way joins in a matter of
385
+ microseconds
386
+ Join reordering is automatic and usually works well enough that
387
+ programmers do not have to think about it, especially if ANALYZE
388
+ has been used to gather statistics about the available indexes,
389
+ though occasionally some hints from the programmer are needed.
390
+ Consider, for example, the following schema:
391
+ The schema above defines a directed graph with the ability to store a
392
+ name at each node. Now consider a query against this schema:
393
+ This query asks for is all information about edges that go from
394
+ nodes labeled "alice" to nodes labeled "bob".
395
+ The query optimizer in SQLite has basically two choices on how to
396
+ implement this query. (There are actually six different choices, but
397
+ we will only consider two of them here.)
398
+ Pseudocode below demonstrating these two choices.
399
+ Option 1:
400
+ Option 2:
401
+ The same indexes are used to speed up every loop in both implementation
402
+ options.
403
+ The only difference in these two query plans is the order in which
404
+ the loops are nested.
405
+ So which query plan is better? It turns out that the answer depends on
406
+ what kind of data is found in the node and edge tables.
407
+ Let the number of alice nodes be M and the number of bob nodes be N.
408
+ Consider two scenarios. In the first scenario, M and N are both 2 but
409
+ there are thousands of edges on each node. In this case, option 1 is
410
+ preferred. With option 1, the inner loop checks for the existence of
411
+ an edge between a pair of nodes and outputs the result if found.
412
+ Because there are only 2 alice and bob nodes each, the inner loop
413
+ only has to run four times and the query is very quick. Option 2 would
414
+ take much longer here. The outer loop of option 2 only executes twice,
415
+ but because there are a large number of edges leaving each alice node,
416
+ the middle loop has to iterate many thousands of times. It will be
417
+ much slower. So in the first scenario, we prefer to use option 1.
418
+ Now consider the case where M and N are both 3500. Alice nodes are
419
+ abundant. This time suppose each of these nodes is connected by only one
420
+ or two edges. Now option 2 is preferred. With option 2,
421
+ the outer loop still has to run 3500 times, but the middle loop only
422
+ runs once or twice for each outer loop and the inner loop will only
423
+ run once for each middle loop, if at all. So the total number of
424
+ iterations of the inner loop is around 7000. Option 1, on the other
425
+ hand, has to run both its outer loop and its middle loop 3500 times
426
+ each, resulting in 12 million iterations of the middle loop.
427
+ Thus in the second scenario, option 2 is nearly 2000 times faster
428
+ than option 1.
429
+ So you can see that depending on how the data is structured in the table,
430
+ either query plan 1 or query plan 2 might be better. Which plan does
431
+ SQLite choose by default? As of version 3.6.18, without running ANALYZE ,
432
+ SQLite will choose option 2.
433
+ If the ANALYZE command is run in order to gather statistics,
434
+ a different choice might be made if the statistics indicate that the
435
+ alternative is likely to run faster.
436
+ 7.1. Manual Control Of Join Order
437
+ SQLite almost always picks the best join order automatically. It is
438
+ very rare that a developer needs to intervene to give the query planner
439
+ hints about the best join order. The best policy is to make use
440
+ of PRAGMA optimize to ensure that the query planner has access to
441
+ up-to-date statistics on the shape of the data in the database.
442
+ This section describes techniques by which developers can control the
443
+ join order in SQLite, to work around any performance problems that may
444
+ arise. However, the use of these techniques is not recommended, except
445
+ as a last resort.
446
+ If you do encounter a situation where SQLite is picking a suboptimal
447
+ join order even after running PRAGMA optimize , please report your
448
+ situation on the SQLite Community Forum so
449
+ that the SQLite maintainers can make new refinements to the query planner
450
+ such that manual intervention is not required.
451
+ 7.1.1. Manual Control Of Query Plans Using SQLITE_STAT Tables
452
+ SQLite provides the ability for advanced programmers to exercise control
453
+ over the query plan chosen by the optimizer. One method for doing this
454
+ is to fudge the ANALYZE results in the sqlite_stat1 table.
455
+ 7.1.2. Manual Control of Query Plans using CROSS JOIN
456
+ Programmers can force SQLite to use a particular loop nesting order
457
+ for a join by using the CROSS JOIN operator instead of just JOIN,
458
+ INNER JOIN, NATURAL JOIN, or a "," join. Though CROSS JOINs are
459
+ commutative in theory, SQLite chooses to never reorder the tables in
460
+ a CROSS JOIN. Hence, the left table of a CROSS JOIN will always be
461
+ in an outer loop relative to the right table.
462
+ In the following query, the optimizer is free to reorder the
463
+ tables of FROM clause any way it sees fit:
464
+ In the following logically equivalent formulation of the same query,
465
+ the substitution of "CROSS JOIN" for the "," means that the order
466
+ of tables must be N1, E, N2.
467
+ In the latter query, the query plan must be
468
+ option 2 . Note that
469
+ you must use the keyword "CROSS" in order to disable the table reordering
470
+ optimization; INNER JOIN, NATURAL JOIN, JOIN, and other similar
471
+ combinations work just like a comma join in that the optimizer is
472
+ free to reorder tables as it sees fit. (Table reordering is also
473
+ disabled on an outer join, but that is because outer joins are not
474
+ associative or commutative. Reordering tables in OUTER JOIN changes
475
+ the result.)
476
+ See " The Fossil NGQP Upgrade Case Study " for another real-world example
477
+ of using CROSS JOIN to manually control the nesting order of a join.
478
+ The query planner checklist found later in the same document provides
479
+ further guidance on manual control of the query planner.
480
+ 8. Choosing Between Multiple Indexes
481
+ Each table in the FROM clause of a query can use at most one index
482
+ (except when the OR-clause optimization comes into
483
+ play)
484
+ and SQLite strives to use at least one index on each table. Sometimes,
485
+ two or more indexes might be candidates for use on a single table.
486
+ For example:
487
+ For the SELECT statement above, the optimizer can use the ex2i1 index
488
+ to lookup rows of ex2 that contain x=5 and then test each row against
489
+ the y=6 term. Or it can use the ex2i2 index to lookup rows
490
+ of ex2 that contain y=6 then test each of those rows against the
491
+ x=5 term.
492
+ When faced with a choice of two or more indexes, SQLite tries to estimate
493
+ the total amount of work needed to perform the query using each option.
494
+ It then selects the option that gives the least estimated work.
495
+ To help the optimizer get a more accurate estimate of the work involved
496
+ in using various indexes, the user may optionally run the ANALYZE command.
497
+ The ANALYZE command scans all indexes of database where there might
498
+ be a choice between two or more indexes and gathers statistics on the
499
+ selectiveness of those indexes. The statistics gathered by
500
+ this scan are stored in special database tables names shows names all
501
+ begin with " sqlite_stat ".
502
+ The content of these tables is not updated as the database
503
+ changes so after making significant changes it might be prudent to
504
+ rerun ANALYZE .
505
+ The results of an ANALYZE command are only available to database connections
506
+ that are opened after the ANALYZE command completes.
507
+ The various sqlite_stat N tables contain information on how
508
+ selective the various indexes are. For example, the sqlite_stat1
509
+ table might indicate that an equality constraint on column x reduces the
510
+ search space to 10 rows on average, whereas an equality constraint on
511
+ column y reduces the search space to 3 rows on average. In that case,
512
+ SQLite would prefer to use index ex2i2 since that index is more selective.
513
+ 8.1. Disqualifying WHERE Clause Terms using Unary-"+"
514
+ Note: Disqualifying WHERE clause terms this way is not recommended.
515
+ This is a work-around.
516
+ Only do this as a last resort to get the performance you need. If you
517
+ find a situation where this work-around is necessary, please report the
518
+ situation on the SQLite Community Forum so
519
+ that the SQLite maintainers can try to improve the query planner such
520
+ that the work-around is no longer required for your situation.
521
+ Terms of the WHERE clause can be manually disqualified for use with
522
+ indexes by prepending a unary + operator to the column name. The
523
+ unary + is a no-op and will not generate any byte code in the prepared
524
+ statement.
525
+ However, the unary + operator will prevent the term from
526
+ constraining an index.
527
+ So, in the example above, if the query were rewritten as:
528
+ The + operator on the x column will prevent that term from
529
+ constraining an index. This would force the use of the ex2i2 index.
530
+ Note that the unary + operator also removes
531
+ type affinity from
532
+ an expression, and in some cases this can cause subtle changes in
533
+ the meaning of an expression.
534
+ In the example above,
535
+ if column x has TEXT affinity
536
+ then the comparison "x=5" will be done as text. The + operator
537
+ removes the affinity. So the comparison " +x=5 " will compare the text
538
+ in column x with the numeric value 5 and will always be false.
539
+ 8.2. Range Queries
540
+ Consider a slightly different scenario:
541
+ Further suppose that column x contains values spread out
542
+ between 0 and 1,000,000 and column y contains values
543
+ that span between 0 and 1,000. In that scenario,
544
+ the range constraint on column x should reduce the search space by
545
+ a factor of 10,000 whereas the range constraint on column y should
546
+ reduce the search space by a factor of only 10. So the ex2i1 index
547
+ should be preferred.
548
+ SQLite will make this determination, but only if it has been compiled
549
+ with SQLITE_ENABLE_STAT3 or SQLITE_ENABLE_STAT4 .
550
+ The SQLITE_ENABLE_STAT3 and SQLITE_ENABLE_STAT4 options causes
551
+ the ANALYZE command to collect a histogram of column content in the
552
+ sqlite_stat3 or sqlite_stat4 tables and to use this histogram to
553
+ make a better guess at the best query to use for range constraints
554
+ such as the above. The main difference between STAT3 and STAT4 is
555
+ that STAT3 records histogram data for only the left-most column of
556
+ an index whereas STAT4 records histogram data for all columns of an
557
+ index. For single-column indexes, STAT3 and STAT4 work the same.
558
+ The histogram data is only useful if the right-hand side of the constraint
559
+ is a simple compile-time constant or parameter and not an expression.
560
+ Another limitation of the histogram data is that it only applies to the
561
+ left-most column on an index. Consider this scenario:
562
+ Here the inequalities are on columns x and y which are not the
563
+ left-most index columns. Hence, the histogram data is useless in helping
564
+ to choose between the range constraints on columns x and y.
565
+ 9. Covering Indexes
566
+ When doing an indexed lookup of a row, the usual procedure is to
567
+ do a binary search on the index to find the index entry, then extract
568
+ the rowid from the index and use that rowid to do a binary search on
569
+ the original table. Thus a typical indexed lookup involves two
570
+ binary searches.
571
+ If, however, all columns that were to be fetched from the table are
572
+ already available in the index itself, SQLite will use the values
573
+ contained in the index and will never look up the original table
574
+ row. This saves one binary search for each row and can make many
575
+ queries run twice as fast.
576
+ When an index contains all of the data needed for a query and when the
577
+ original table never needs to be consulted, we call that index a
578
+ "covering index".
579
+ 10. ORDER BY Optimizations
580
+ SQLite attempts to use an index to satisfy the ORDER BY clause of a
581
+ query when possible.
582
+ When faced with the choice of using an index to satisfy WHERE clause
583
+ constraints or satisfying an ORDER BY clause, SQLite does the same
584
+ cost analysis described above
585
+ and chooses the index that it believes will result in the fastest answer.
586
+ SQLite will also attempt to use indexes to help satisfy GROUP BY clauses
587
+ and the DISTINCT keyword. If the nested loops of the join can be arranged
588
+ such that rows that are equivalent for the GROUP BY or for the DISTINCT are
589
+ consecutive, then the GROUP BY or DISTINCT logic can determine if the
590
+ current row is part of the same group or if the current row is distinct
591
+ simply by comparing the current row to the previous row.
592
+ This can be much faster than the alternative of comparing each row to
593
+ all prior rows.
594
+ 10.1. Partial ORDER BY via Index
595
+ If a query contains an ORDER BY clause with multiple terms, it might
596
+ be that SQLite can use indexes to cause rows to come out in the order
597
+ of some prefix of the terms in the ORDER BY but that later terms in
598
+ the ORDER BY are not satisfied. In that case, SQLite does block sorting.
599
+ Suppose the ORDER BY clause has four terms and the natural order of the
600
+ query results in rows appearing in order of the first two terms. As
601
+ each row is output by the query engine and enters the sorter, the
602
+ outputs in the current row corresponding to the first two terms of
603
+ the ORDER BY are compared against the previous row. If they have
604
+ changed, the current sort is finished and output and a new sort is
605
+ started. This results in a slightly faster sort. Even bigger
606
+ advantages are that many fewer rows need to be held in memory,
607
+ reducing memory requirements, and outputs can begin to appear before
608
+ the core query has run to completion.
609
+ 11. Subquery Flattening
610
+ When a subquery occurs in the FROM clause of a SELECT, the simplest
611
+ behavior is to evaluate the subquery into a transient table, then run
612
+ the outer SELECT against the transient table. Such a plan
613
+ can be suboptimal since the transient table will not have any indexes
614
+ and the outer query (which is likely a join) will be forced to either
615
+ do a full table scan on the transient table or else construct a
616
+ query-time index on the transient table, neither of which is
617
+ is particularly fast.
618
+ To overcome this problem, SQLite attempts to flatten subqueries in
619
+ the FROM clause of a SELECT.
620
+ This involves inserting the FROM clause of the subquery into the
621
+ FROM clause of the outer query and rewriting expressions in
622
+ the outer query that refer to the result set of the subquery.
623
+ For example:
624
+ Would be rewritten using query flattening as:
625
+ There is a long list of conditions that must all be met in order for
626
+ query flattening to occur. Some of the constraints are marked as
627
+ obsolete by italic text. These extra constraints are retained in the
628
+ documentation to preserve the numbering of the other constraints.
629
+ Casual readers are not expected to understand all of these rules.
630
+ The point here is that flattening rules are subtle and complex.
631
+ There have been multiple bugs over the years caused by
632
+ over-aggressive query flattening. On the other hand, performance
633
+ of complex queries and/or queries involving views tends to suffer
634
+ if query flattening is more conservative.
635
+ (Obsolete)
636
+ (Obsolete)
637
+ If the subquery is the right operand of a LEFT JOIN then
638
+ the subquery may not be a join, and
639
+ the FROM clause of the subquery may
640
+ not contain a virtual table, and
641
+ the outer query may not be DISTINCT.
642
+ The subquery is not DISTINCT.
643
+ (Obsolete - subsumed into constraint 4)
644
+ (Obsolete)
645
+ The subquery has a FROM clause.
646
+ The subquery does not use LIMIT or the outer query is
647
+ not a join.
648
+ The subquery does not use LIMIT or the outer query
649
+ does not use aggregates.
650
+ (Obsolete)
651
+ The subquery and the outer query do not both have ORDER BY clauses.
652
+ (Obsolete - subsumed into constraint 3)
653
+ The subquery and outer query do not both use LIMIT.
654
+ The subquery does not use OFFSET.
655
+ If the outer query is part of a compound select, then the
656
+ subquery may not have a LIMIT clause.
657
+ If the outer query is an aggregate, then the subquery may
658
+ not contain ORDER BY.
659
+ If the sub-query is a compound SELECT, then
660
+ all compound operators must be UNION ALL, and
661
+ no terms with the subquery compound may be aggregate
662
+ or DISTINCT, and
663
+ every term within the subquery must have a FROM clause, and
664
+ the outer query may not be an aggregateor DISTINCT query.
665
+ the subquery may not contain window functions.
666
+ the subquery must not be the right-hand side of a LEFT JOIN.
667
+ either the subquery is the first element of the outer query
668
+ or there are not RIGHT or FULL JOINs in any arm of the subquery.
669
+ the corresponding result set expressions in all arms of the
670
+ compound subquery must have the same affinity .
671
+ The parent and sub-query may contain WHERE clauses. Subject to
672
+ rules (11), (12) and (13), they may also contain ORDER BY,
673
+ LIMIT and OFFSET clauses.
674
+ If the sub-query is a compound select, then all terms of the
675
+ ORDER by clause of the parent must be simple references to
676
+ columns of the sub-query.
677
+ If the subquery uses LIMIT then the outer query may not
678
+ have a WHERE clause.
679
+ If the sub-query is a compound select, then it must not use
680
+ an ORDER BY clause.
681
+ If the subquery uses LIMIT, then the outer query may not be
682
+ DISTINCT.
683
+ The subquery may not be a recursive CTE.
684
+ If the outer query is a recursive CTE, then the sub-query
685
+ may not be a compound query.
686
+ (Obsolete)
687
+ Neither the subquery nor the outer query may contain
688
+ a window function in the result set nor the ORDER BY clause.
689
+ The subquery may not be the right operand of a RIGHT
690
+ or FULL OUTER JOIN.
691
+ The subquery may not contain a FULL or RIGHT JOIN unless it
692
+ is the first element of the parent query. Two subcases:
693
+ the subquery is not a compound query.
694
+ the subquery is a compound query and the RIGHT JOIN occurs
695
+ in any arm of the compound query. (See also (17g)).
696
+ The subquery is not a MATERIALIZED CTE.
697
+ Query flattening is an important optimization when views are used as
698
+ each use of a view is translated into a subquery.
699
+ 12. Subquery Co-routines
700
+ SQLite implements FROM-clause subqueries in one of three ways:
701
+ Flatten the subquery into its outer query
702
+ Evaluate the subquery into a transient table that exists for
703
+ the duration of the one SQL statement that is being evaluated,
704
+ then run the outer query against that transient table.
705
+ Evaluate the subquery in a co-routine that runs in parallel with
706
+ the outer query, providing rows to the outer query as needed.
707
+ This section describes the third technique: implementing the subquery
708
+ as a co-routine.
709
+ A co-routine is like a subroutine in that it runs in the same thread
710
+ as the caller and eventually returns control back to the caller. The
711
+ difference is that a co-routine also has the ability to return
712
+ before it has finished, and then resume where it left off the next
713
+ time it is called.
714
+ When a subquery is implemented as a co-routine, byte-code is generated
715
+ to implement the subquery as if it were a standalone query, except
716
+ instead of returning rows of results back to the application, the
717
+ co-routine yields control back to the caller after each row is computed.
718
+ The caller can then use that one computed row as part of its computation,
719
+ then invoke the co-routine again when it is ready for the next row.
720
+ Co-routines are better than storing the complete result set of the subquery
721
+ in a transient table because co-routines use less memory. With a co-routine,
722
+ only a single row of the result needs to be remembered, whereas all rows of
723
+ the result must be stored for a transient table. Also, because the
724
+ co-routine does not need to run to completion before the outer query
725
+ begins its work, the first rows of output can appear much sooner, and if
726
+ the overall query is abandoned before it has finished, less work is done
727
+ overall.
728
+ On the other hand, if the result of the subquery must be scanned multiple
729
+ times (because, for example, it is just one table in a join) then it
730
+ is better to use a transient table to remember the entire result of the
731
+ subquery, in order to avoid computing the subquery more than once.
732
+ 12.1. Using Co-routines to Defer Work until after the Sorting
733
+ As of SQLite version 3.21.0 (2017-10-24), the query planner will
734
+ always prefer to use a co-routine to implement FROM-clause subqueries
735
+ that contains an ORDER BY clause and that are not part of a join when
736
+ the result set of the outer query is "complex". This feature allows
737
+ applications to shift expensive computations from before the
738
+ sorter until after the sorter, which can result in faster operation.
739
+ For example, consider this query:
740
+ The goal of this query is to compute some value for the five most
741
+ recent entries in the table. In the query above, the
742
+ "expensive_function()" is invoked prior to the sort and thus is
743
+ invoked on every row of the table, even
744
+ rows that are ultimately omitted due to the LIMIT clause.
745
+ A co-routine can be used to work around this:
746
+ In the revised query, the subquery implemented by a co-routine computes
747
+ the five most recent values for "a". Those five values are passed from the
748
+ co-routine up into the outer query where the "expensive_function()" is
749
+ invoked on only the specific rows that the application cares about.
750
+ The query planner in future versions of SQLite might grow smart enough
751
+ to make transformations such as the above automatically, in both directions.
752
+ That is to say, future versions of SQLite might transform queries of the
753
+ first form into the second, or queries written the second way into the
754
+ first. As of SQLite version 3.22.0 (2018-01-22), the query planner
755
+ will flatten the subquery if the outer query does not make use of any
756
+ user-defined functions or subqueries in its result set. For the examples
757
+ shown above, however, SQLite implements each of the queries as
758
+ written.
759
+ 13. The MIN/MAX Optimization
760
+ Queries that contain a single MIN() or MAX() aggregate function whose
761
+ argument is the left-most column of an index might be satisfied
762
+ by doing a single index lookup rather than by scanning the entire table.
763
+ Examples:
764
+ 14. Automatic Query-Time Indexes
765
+ When no indexes are available to aid the evaluation of a query, SQLite
766
+ might create an automatic index that lasts only for the duration
767
+ of a single SQL statement.
768
+ Automatic indexes are also sometimes called "Query-time indexes".
769
+ Since the cost of constructing the automatic or query-time index is
770
+ O(NlogN) (where N is the number of entries in the table) and the cost of
771
+ doing a full table scan is only O(N), an automatic index will
772
+ only be created if SQLite expects that the lookup will be run more than
773
+ logN times during the course of the SQL statement. Consider an example:
774
+ In the query above, if both t1 and t2 have approximately N rows, then
775
+ without any indexes the query will require O(N*N) time. On the other
776
+ hand, creating an index on table t2 requires O(NlogN) time and using
777
+ that index to evaluate the query requires an additional O(NlogN) time.
778
+ In the absence of ANALYZE information, SQLite guesses that N is one
779
+ million and hence it believes that constructing the automatic index will
780
+ be the cheaper approach.
781
+ An automatic query-time index might also be used for a subquery:
782
+ In this example, the t2 table is used in a subquery to translate values
783
+ of the t1.b column. If each table contains N rows, SQLite expects that
784
+ the subquery will run N times, and hence it will believe it is faster
785
+ to construct an automatic, transient index on t2 first and then use
786
+ that index to satisfy the N instances of the subquery.
787
+ The automatic indexing capability can be disabled at run-time using
788
+ the automatic_index pragma . Automatic indexing is turned on by
789
+ default, but this can be changed so that automatic indexing is off
790
+ by default using the SQLITE_DEFAULT_AUTOMATIC_INDEX compile-time option.
791
+ The ability to create automatic indexes can be completely disabled by
792
+ compiling with the SQLITE_OMIT_AUTOMATIC_INDEX compile-time option.
793
+ In SQLite version 3.8.0 (2013-08-26) and later,
794
+ an SQLITE_WARNING_AUTOINDEX message is sent
795
+ to the error log every time a statement is prepared that uses an
796
+ automatic index. Application developers can and should use these warnings
797
+ to identify the need for new persistent indexes in the schema.
798
+ Do not confuse automatic indexes with the internal indexes (having names
799
+ like "sqlite_autoindex_ table _ N ") that are sometimes
800
+ created to implement a PRIMARY KEY constraint or UNIQUE constraint .
801
+ The automatic indexes described here exist only for the duration of a
802
+ single query, are never persisted to disk, and are only visible to a
803
+ single database connection. Internal indexes are part of the implementation
804
+ of PRIMARY KEY and UNIQUE constraints, are long-lasting and persisted
805
+ to disk, and are visible to all database connections. The term "autoindex"
806
+ appears in the names of internal indexes for legacy reasons and does
807
+ not indicate that internal indexes and automatic indexes are related.
808
+ 14.1. Hash Joins
809
+ An automatic index is almost the same thing as a
810
+ hash join . The only difference
811
+ is that a B-Tree is used instead of a hash table. If you are willing to
812
+ say that the transient B-Tree constructed for an automatic index is
813
+ really just a fancy hash table, then a query that uses an automatic
814
+ index is just a hash join.
815
+ SQLite constructs a transient index instead of a hash table in this
816
+ instance because it already has a robust and high performance B-Tree
817
+ implementation at hand, whereas a hash-table would need to be added.
818
+ Adding a separate hash table implementation to handle this one case
819
+ would increase the size of the library (which is designed for use on
820
+ low-memory embedded devices) for minimal performance gain. SQLite might
821
+ be enhanced with a hash-table implementation someday, but for now it seems
822
+ better to continue using automatic indexes in cases where client/server
823
+ database engines might use a hash join.
824
+ 15. The Predicate Push-Down Optimization
825
+ If a subquery cannot be flattened into the outer query, it might
826
+ still be possible to enhance performance by "pushing down" WHERE clause
827
+ terms from the outer query into the subquery. Consider an example:
828
+ The view v1 cannot be flattened because it is DISTINCT. It must
829
+ instead be run as a subquery with the results being stored in a
830
+ transient table, then the join is performed between t2 and the
831
+ transient table. The push-down optimization pushes down the
832
+ "b BETWEEN 10 AND 20" term into the view. This makes the transient
833
+ table smaller, and helps the subquery to run faster if there
834
+ is an index on t1.b. The resulting evaluation is like this:
835
+ The WHERE-clause push-down optimization cannot always be used. For example,
836
+ if the subquery contains a LIMIT, then pushing down any part of
837
+ the WHERE clause from the outer query could change the result of
838
+ the inner query. There are other restrictions, explained in a
839
+ comment in the source code on the pushDownWhereTerms() routine
840
+ that implements this optimization.
841
+ Do not confuse this optimization with the optimization by a similar name
842
+ in MySQL. The MySQL push-down optimization changes the order of evaluation
843
+ of WHERE-clause constraints such that those that can be evaluated using
844
+ only the index and without having to find the corresponding table row are
845
+ evaluated first, thus avoiding an unnecessary table row lookup if the
846
+ constraint fails. For disambiguation, SQLite calls this the
847
+ "MySQL push-down optimization". SQLite does do the MySQL push-down
848
+ optimization too, in addition to the WHERE-clause push-down optimization.
849
+ But the focus of this section is the WHERE-clause push-down optimization.
850
+ 16. The OUTER JOIN Strength Reduction Optimization
851
+ An OUTER JOIN (either a LEFT JOIN, a RIGHT JOIN, or a FULL JOIN)
852
+ can sometimes be simplified. A LEFT or RIGHT JOIN can be converted
853
+ into an ordinary (INNER) JOIN, or a FULL JOIN might be converted into
854
+ either a LEFT or a RIGHT JOIN. This can happen if there are terms
855
+ in the WHERE clause that guarantee the same result after simplification.
856
+ For example, if any
857
+ column in the right-hand table of the LEFT JOIN must be non-NULL
858
+ in order for the WHERE clause to be true, then the LEFT JOIN is
859
+ demoted to an ordinary JOIN.
860
+ The theorem prover that determines whether a join can be simplified is
861
+ imperfect. It sometimes returns a false negative. In other words,
862
+ it sometimes fails to prove that reducing the strength of an OUTER JOIN
863
+ is safe when in fact it is safe.
864
+ For example, the prover does not know
865
+ the datetime() SQL function will always return NULL if its first
866
+ argument is NULL, and so it will not recognize that the LEFT JOIN
867
+ in the following query could be strength-reduced:
868
+ It is possible that future enhancements to the prover might enable it
869
+ to recognize that NULL inputs to certain built-in functions
870
+ always result in a NULL answer. However, not all built-in
871
+ functions have that property (for example coalesce() ) and, of
872
+ course, the prover will never be able to reason about
873
+ application-defined SQL functions .
874
+ 17. The Omit OUTER JOIN Optimization
875
+ Sometimes a LEFT or RIGHT JOIN can be completely omitted from a query without
876
+ changing the result. This can happen if all of the following are
877
+ true:
878
+ The query is not an aggregate
879
+ Either the query is DISTINCT or else the ON or USING clause
880
+ on the OUTER JOIN constrains the join such that it matches
881
+ only a single row
882
+ The right-hand table of the LEFT JOIN or the left-hand table of
883
+ a RIGHT JOIN is not be used anywhere
884
+ in the query outside of its own USING or ON clause.
885
+ OUTER JOIN elimination often comes up when OUTER JOINs are used
886
+ inside of views, and then the view is used in such as way that
887
+ none of the columns on the right-hand table of the LEFT JOIN or
888
+ on the left-hand table of a RIGHT JOIN are referenced.
889
+ Here is a simple example of omitting a LEFT JOIN:
890
+ The t2 table is completely unused in the query above, and so the
891
+ query planner is able to implement the query as if it were written:
892
+ As of this writing, only LEFT JOINs are eliminated. This optimize
893
+ has not yet been generalized to work with RIGHT JOINs as RIGHT JOIN
894
+ is a relatively new addition to SQLite. That asymmetry will probably
895
+ be corrected in a future release.
896
+ 18. The Constant Propagation Optimization
897
+ When a WHERE clause contains two or more equality constraints connected
898
+ by the AND operator such that all of the affinities of the various
899
+ constraints are the same, then SQLite might use the transitive property
900
+ of equality to construct new "virtual" constraints that can be used to
901
+ simplify expressions and/or improve performance. This is called the
902
+ "constant-propagation optimization".
903
+ For example, consider the following schema and query:
904
+ SQLite looks at the "a=b" and "b=5" constraints and deduces that
905
+ if those two constraints are true, then it must also be the case
906
+ that "a=5" is true. This means that the desired row can be looked up
907
+ quickly using a value of 5 for the INTEGER PRIMARY KEY.
908
+ This page was last updated on 2025-05-31 13:08:22Z