Hi,

The SQLite documentation does a good job explaining what an 'automatic index' 
is [1], so when someone looks at 'explain query plan' output and sees something 
like this they get worried:
SEARCH TABLE fmeta USING INDEX sqlite_autoindex_fmeta_1 (file_id=?)

The link above[1] uses #autoindex, the log code associated with it [3] is 
called SQLITE_WARNING_AUTOINDEX, so you can see why this is a bit confusing.

The SQLite source code explains that 'sqlite3_autoindex_*' is the index created 
for PRIMARY KEY and UNIQUE constraints (i.e. a persistent index created at 
table creation time):
  ** If pName==0 it means that we are
  ** dealing with a primary key or UNIQUE constraint.  We have to invent our
  ** own name.

 /* This routine has been called to create an automatic index as a
    ** result of a PRIMARY KEY or UNIQUE clause on a column definition, or
    ** a PRIMARY KEY or UNIQUE clause following the column definitions. */

Indeed the column from the query plan is part of a PRIMARY KEY, and there was 
no warning logged via SQLITE3_CONFIG_LOG so there is nothing to worry about:
CREATE TABLE fmeta (file_id INTEGER NOT NULL REFERENCES files(fid) ON DELETE 
CASCADE ON UPDATE CASCADE, key TEXT (256) NOT NULL, value BLOB (1024) NOT NULL, 
PRIMARY KEY(file_id, key));

I would suggest adding an explanation about sqlite3_autoindex_ to the 
documentation.

For example add to [1]:
-- example --
You can also use [EXPLAIN QUERY PLAN][2] to check for automatic index usage at 
query preparation time.
-- example --

And add to [2]:
-- example --

1.5 Automatic indices

SQLite may create automatic indices in certain situations [1]. You can use 
EXPLAIN QUERY PLAN to check for this, following the example from [1]:
sqlite> EXPLAIN QUERY PLAN SELECT * FROM t1, t2 WHERE a=c;
sele  order          from  deta
----  -------------  ----  ----
0     0              0     SCAN TABLE t1
0     1              1     SEARCH TABLE t2 USING AUTOMATIC COVERING INDEX (c=?)

You can create a persistent index so that SQLite doesn't have to create a new 
index at every query:
sqlite> CREATE INDEX my_persistent_index ON t2(c);
sqlite> EXPLAIN QUERY PLAN SELECT * FROM t1, t2 WHERE a=c;
sele  order          from  deta
----  -------------  ----  ----
0     0              0     SCAN TABLE t1
0     1              1     SEARCH TABLE t2 USING INDEX my_persistent_index (c=?)

Or if your entries in the column are unique you can use a primary key or unique 
constraint with same effect:
sqlite> CREATE TABLE t3(c PRIMARY KEY,d);
sqlite> EXPLAIN QUERY PLAN SELECT * FROM t1, t3 WHERE a=c;
sele  order          from  deta
----  -------------  ----  ----
0     0              0     SCAN TABLE t1
0     1              1     SEARCH TABLE t3 USING INDEX sqlite_autoindex_t3_1 
(c=?)


Note that sqlite_autoindex_* is the name given by SQLite to indexes created 
automatically as a result of a PRIMARY KEY or UNIQUE clause.

-- example --

[1]: https://www.sqlite.org/optoverview.html#autoindex
[2]: https://www.sqlite.org/eqp.html#autoindex
[3]: https://www.sqlite.org/rescode.html#warning_autoindex

-- 
Edwin T?r?k | Co-founder and Lead Developer

Skylable open-source object storage: reliable, fast, secure
http://www.skylable.com

Reply via email to