SQLite 不使用索引进行删除

问题描述 投票:0回答:1

给定一个类似于

的模式
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
sqlite
1个回答
0
投票

使用索引会给出“无查询解决方案”错误。

这是一条线索。简而言之,指定的索引不能使用(如果强制)。

这是由于:-

要被索引使用,术语通常必须采用以下形式之一:

  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 评论)

您可能希望阅读:-

除了之前链接的文档之外。

© www.soinside.com 2019 - 2024. All rights reserved.