给定一个类似于
的模式CREATE TABLE `EventStatus` (`id` varchar(1024) NOT NULL,`node` varchar(255) DEFAULT NULL,`lastUpdate` bigint DEFAULT NULL,`deleted` integer DEFAULT 0, `owner` varchar(1024) DEFAULT '', `body` varchar(10240) DEFAULT NULL, PRIMARY KEY (`id`, `node`) );
CREATE INDEX EventStatus_lastUpdate on EventStatus (deleted, lastUpdate);
SQLite3将使用索引来统计行
where deleted
,并删除行where deleted = 1
,但不删除行where deleted
。这是为什么呢?使用 indexed by
会出现“无查询解决方案”错误。
使用 v3.31.1 CLI。
sqlite> delete from eventstatus where deleted='1';
QUERY PLAN
`--SEARCH TABLE eventstatus USING INDEX EventStatus_lastUpdate (deleted=?)
sqlite> select count() from eventupdates where deleted;
QUERY PLAN
`--SCAN TABLE eventupdates USING COVERING INDEX EventUpdates_lastUpdate
0
sqlite> delete from eventupdates where deleted;
QUERY PLAN
`--SCAN TABLE eventupdates
使用索引会给出“无查询解决方案”错误。
这是一条线索。简而言之,指定的索引不能使用(如果强制)。
这是由于:-
要被索引使用,术语通常必须采用以下形式之一:
column = expression
column IS expression
column > expression
column >= expression
column < expression
column <= expression
expression = column
expression IS column
expression > column
expression >= column
expression < column
expression <= column
column IN (expression-list)
column IN (subquery)
column IS NULL
column LIKE pattern
column GLOB pattern
即
deleted
是一个不等式,与 deleted=1
或 deleted='1'
不同,强制使用索引(使用 INDEXED BY ....
)是一个错误(如果不使用 EXPLAIN QUERY PLAN
则会出现错误)。
在没有
INDEXED BY
强制使用索引的情况下,查询优化器将决定如何定位行。
我相信 count() 函数也可以发挥作用
EXPLAIN QUERY PLAN SELECT count() FROM eventstatus WHERE deleted;
结果使用覆盖索引扫描表eventstatus EventStatus_lastUpdate
但是;
EXPLAIN QUERY PLAN SELECT * FROM eventstatus /*INDEXED BY eventstatus_lastupdate <<<<< OUCH*/ WHERE deleted;
结果为 SCAN TABLE 事件状态
INDEXED BY is included then the
没有查询解决方案`结果(因此 OUCH 评论)您可能希望阅读:-
除了之前链接的文档之外。