Filip,
I don't suppose it would fit your needs to index on the column you're
comparing rather than on "id" would it? That would cause the query
planner to use your indexes, I believe.
create index "i1" on "t" (uniqueID) where UniqueId ==55;
Alternatively, you can create an "unnecessary" compound index such as
create index "i1" on "t" (uniqueID, id) where UniqueId ==55;
Even though the documentation seems to explicitly allow creating partial
indexes on columns other than the indexed column:
"The columns referenced in the WHERE clause of a partial index can be
any of the columns in the table, not just columns that happen to be indexed.
"
(It may well be that I'm missing something myself.)
I tried experimenting with 3.8.8, removing references to NULL and using "==
55" as a simple test condition; results follow. Your problem did not go
away when I got rid of NULL checking, but creation of a partial index on
column "id" which tests instead on column "uniqueID" DID cause the index to
go unused. (Whether sqlite is working properly or not -- I'll leave that
for others to say.)
sqlite>
sqlite> /* Test comparing UniqueID to 55 rather than to null */
sqlite> /* Note that index is on column "id" and not "uniqueID" */
sqlite> /* EXPLAIN Q. Plan shows partial index would not be invoked*/
sqlite> drop table if exists t;
sqlite> create table "t" ("id" INTEGER NOT NULL PRIMARY KEY, "flags"
INTEGER,
...> "uniqueId", "syncFolder" INTEGER);
sqlite> ANALYZE;
sqlite> create index "i1" on "t" (uniqueID, id) where UniqueId ==55;
sqlite> ANALYZE;
sqlite> explain query plan select * from "t" where UniqueID ==55;
0|0|0|SEARCH TABLE t USING INDEX i1 (uniqueId=?)
sqlite>
sqlite>
sqlite>
sqlite> /* Try to see if it fails only on INTEGER PRIMARY KEY.*/
sqlite> /*Don't use variable "id" at all, use "flags" instead.*/
sqlite> /* Query planner would still not use index */
sqlite> drop table if exists t;
sqlite> create table "t" ("id" INTEGER NOT NULL PRIMARY KEY, "flags"
INTEGER,
...> "uniqueId", "syncFolder" INTEGER);
sqlite>
sqlite> ANALYZE;
sqlite> create index "i1" on "t" (flags) where UniqueId ==55;
sqlite> ANALYZE;
sqlite> explain query plan select * from "t" where UniqueID ==55;
0|0|0|SCAN TABLE t
sqlite>
sqlite>
sqlite>
sqlite>
sqlite> /* Try making index compound, with "id" secondary*/
sqlite> /* This DOES provoke the query planner into using the index*/
sqlite> /* (at the expense of some efficiency, I suppose)*/
sqlite> drop table if exists t;
sqlite> create table "t" ("id" INTEGER NOT NULL PRIMARY KEY, "flags"
INTEGER,
...> "uniqueId", "syncFolder" INTEGER);
sqlite> ANALYZE;
sqlite> create index "i1" on "t" (uniqueID, id) where UniqueId ==55;
sqlite> ANALYZE;
sqlite> explain query plan select * from "t" where UniqueID ==55;
0|0|0|SEARCH TABLE t USING INDEX i1 (uniqueId=?)
sqlite>
sqlite>
sqlite> /* Of course it also works if you don't index on column "id" */
sqlite> drop table if exists t;
sqlite> create table "t" ("id" INTEGER NOT NULL PRIMARY KEY, "flags"
INTEGER,
...> "uniqueId", "syncFolder" INTEGER);
sqlite>
sqlite> create index "i1" on "t" (uniqueId) where UniqueId ==55;
sqlite> explain query plan select * from "t" where UniqueID ==55;
0|0|0|SEARCH TABLE t USING INDEX i1 (uniqueId=?)
sqlite>
sqlite> select sqlite_version();
3.8.8
sqlite> pragma compile_options;
ENABLE_FTS3
ENABLE_RTREE
SYSTEM_MALLOC
THREADSAFE=0
sqlite>
*I used windoze pre-compiled exe withOUT STAT4, btw.*