无法理解 UPDATE 查询的 COVERING INDEX 查询计划

Posted

技术标签:

【中文标题】无法理解 UPDATE 查询的 COVERING INDEX 查询计划【英文标题】:Cannot understand COVERING INDEX query plan for UPDATE query 【发布时间】:2016-11-07 14:49:47 【问题描述】:

我有一个如下的 SQLite 表:

CREATE TABLE TableA (ColumnA INTEGER PRIMARY KEY AUTOINCREMENT,
                     ColumnB INTEGER NOT NULL,
                     ColumnC TEXT NOT NULL)

我在这个表上创建了两个索引,如下所示:

CREATE INDEX ColumnB_ColumnC_on_TableA ON TableA (ColumnB ASC, ColumnC ASC)
CREATE INDEX ColumnC_on_TableA ON TableA (ColumnC ASC)

当我对以下查询运行 EXPLAIN QUERY 命令时...

UPDATE TableA SET ColumnB = 1 WHERE ColumnC = '1'

...我看到输出如下...

SEARCH TABLE TableA USING COVERING INDEX ColumnC_on_TableA (ColumnC=?)

我不明白为什么查询计划说ColumnC_on_TableA 索引是一个覆盖索引,而该索引并未覆盖表中的所有列。任何人都可以理解并解释它吗?

【问题讨论】:

【参考方案1】:

covering index 是一个索引,涵盖了在搜索中实际使用的所有列

UPDATE 总是读取/写入整个表行(以及相应的索引条目),但是为了查找要更新的行,不需要读取任何表行的内容。

【讨论】:

感谢 CL 的回复,但我还是不明白。在我的问题示例中,EXPLAIN QUERY PLAN 输出表明使用覆盖索引ColumnC_on_TableA 搜索了TableA。让我困惑的是ColumnC_on_TableA 不是覆盖索引。 (另一个索引是覆盖索引,即ColumnB_ColumnC_on_TableA)我是否错误地阅读/理解了输出? 明白了!现在这是有道理的。举个例子:SELECT * FROM TableA WHERE ColumnC = '1'的查询计划是SEARCH TABLE TableA USING INDEX ColumnC_on_TableA (ColumnC=?)SELECT ColumnC FROM TableA WHERE ColumnC = '1'的查询计划是SEARCH TABLE TableA USING COVERING INDEX ColumnC_on_TableA (ColumnC=?)

以上是关于无法理解 UPDATE 查询的 COVERING INDEX 查询计划的主要内容,如果未能解决你的问题,请参考以下文章

一图读懂mysql的update语句修改管理员密码

HDU - 6185 Covering(暴搜+递推+矩阵快速幂)

更新计划查询时出错:无法更新 update_time

Covering Algorithms:Constructing Rules

2017 ICPC 广西邀请赛1004 Covering

D - Covering HDU - 6185(未解决完)