On Thursday, 2 March, 2017 06:04, Hick Gunter <h...@scigames.at> wrote:
> I tried to create a test table and two indices thus: > >create temp table test (id integer primary key, name text unique, bs > integer, data text); > >create unique index plain on test(name); > >create unique index cover on test(name,bs); Whatever is the reason for creating index plain? There is already an index specified by the use of the "unique" keyword in the table definition. Get rid of it. It is just a waste of space and serves no purpose (other than to confuse you). > NB: The field name has a unique constraint Yes -- and to enforce that constraint (or a primary key constraint where the key is NOT a simple integer primary key alias for the RowID) a unique index is automatically created called sqlite_autoindex_<tablename>_<sequence#>. Since this is the first such index needed by the table definition the index would be called sqlite_autoindex_test_1. > As long as the query mentions the additional field, sqlite chooses the > covering index. > >explain query plan select name,bs from test where name='test' and bs=1; > >sele order from deta > >---- ------------- ---- ---- > >0 0 0 SEARCH TABLE test USING COVERING INDEX cover > (name=? AND bs=?) (~1 rows) It happens to be covering yes, but it is chosen because it contains the two things referenced in the WHERE clauses. > unfortunately if thsi field is dropped from the where clause but remains > in the select list, sqlite misses the covering index > >explain query plan select name,bs from test where name='test'; > >sele order from deta > >---- ------------- ---- ---- > >0 0 0 SEARCH TABLE test USING INDEX plain (name=?) > (~1 rows) > > not having an index at alls causes sqlite to create an automatic index > >drop index cover; > >drop index plain; > >explain query plan select name,bs from test where name='test'; > >sele order from deta > >---- ------------- ---- ---- > >0 0 0 SEARCH TABLE test USING INDEX > sqlite_autoindex_test_1 (name=?) (~1 rows) > > just the same if the index is not unique (even though the first field is) No it does not. This is the index created when the table was defined to enforce your unique constraint. When an index is created temporarily to service a query you will see "USING AUTOMATIC COVERING INDEX" -- the magic word is AUTOMATIC. > >create index plain on test(name); > >create index cover on test(name,bs); > >explain query plan select name,bs from test where name='test'; > >sele order from deta > >---- ------------- ---- ---- > >0 0 0 SEARCH TABLE test USING INDEX > sqlite_autoindex_test_1 (name=?) (~1 rows) > > I guess such a schema would be quite unusual, so this optimization > opportunity is missed. No, it is quite common. However, you need to not muddy the waters by creating duplicate indexes (sqlite will not get confused, however you will confuse yourself), and also run ANALYZE to see if that makes a difference. However, there may also be a wee issue (that I noticed elsewhere) that intentional covering indexes don't seem to always be selected properly if they are declared unique (even if they are unique). Try declaring your covering index without the unique constraint and see if that makes a difference. Maybe this is something Richard can address -- whether or not there is a preference in the covering index selection for a non-unique vs unique index. _______________________________________________ sqlite-users mailing list sqlite-users@mailinglists.sqlite.org http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users