You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQLite执行WHERE deleted的DELETE语句未使用索引的原因咨询

SQLite3 DELETE语句不使用索引的原因分析

核心原因:优化器成本评估与索引适用场景差异

1. 等值条件与非等值条件的成本判断

  • 当执行DELETE FROM eventstatus WHERE deleted='1'时,条件是等值匹配,索引EventStatus_lastUpdate的首列就是deleted,优化器可以快速定位到所有符合条件的索引条目,再通过索引关联到表行(因为这是WITHOUT ROWID表,索引会隐式绑定主键列来定位行),整体成本远低于全表扫描,所以会选择使用索引。
  • 当执行DELETE FROM eventstatus WHERE deleted时,这个写法等价于WHERE deleted != 0(因为deleted是整数类型,非0值会被判定为真)。如果表中满足deleted≠0的行占比很高,优化器会认为:先遍历索引再逐个回表找行的成本,反而比直接全表扫描并过滤行更高,因此选择全表扫描。

2. SELECT COUNT与DELETE的索引使用差异

SELECT COUNT(*) WHERE deleted能使用索引,是因为它属于覆盖索引扫描——只需要读取索引中的deleted列就能判断是否符合条件,不需要回表获取完整行数据,成本极低,所以优化器会优先选择索引。但DELETE必须定位到具体的行才能执行删除操作,无法仅靠索引完成,因此优化器的成本判断逻辑完全不同。

为什么INDEXED BY会报错?

你创建的EventStatus_lastUpdate索引只包含deleted和lastUpdate两列,而这张表是WITHOUT ROWID表(因为指定了复合主键(id, node))。执行DELETE时,SQLite需要唯一确定要删除的行,但该索引缺少主键列id和node,无法提供足够的定位信息,强制使用该索引会导致无法找到具体的行,因此抛出“No query solution”错误。

内容的提问来源于stack exchange,提问作者Pete

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 08:08:24