- In SQLite, joins are implemented as nested loop joins, i.e., SQLite goes through all (maybe filtered) records of one table, and for each one, looks up the matching record(s) in the other table. Which of the two joined tables is chosen as the outer or the inner one depends on which lookup is estimated to be faster.
- In a query, SQLite uses at most one index per table.
- A multi-column index can be used for lookups on a subset of its columns only if all the leftmost columns are used.
For example, your
col1,col2
index can be used for lookups that use bothcol1
andcol2
, or for lookups that use onlycol1
.
In your first query, the two-column index cannot be used for the lookup on col2
.
If the column id
of the other table has an index, SQLite will just use that table as the inner table of the loop. If id
is not indexed either, SQLite is likely to create a temporary index for this query.
In your second query, SQLite is likely to use t1
as the outer table because the WHERE
filter will reduce the number of records that must be looked up in the other table. The two-column index can be used to search for matching col1
records first; then each of those records is joined with t2
.
To check what indexes (if any) are used by a query, execute EXPLAIN QUERY PLAN.