只更新一列,奇怪的执行计划

car*_*reo 0 sql-server execution-plan sql-server-2016

我在我的数据库中记录了最慢的查询,其中一个让我感到惊讶,在列表中显示了很多次,并且执行通常需要很多秒。

UPDATE books SET last_read='2018-12-31 11:23:45' WHERE book_id='15'
Run Code Online (Sandbox Code Playgroud)

book_id 是 int 身份 PK(集群),last_read 是日期时间。查询是用单引号中的 15 编写的,因此需要转换,但我无法想象这是一个大问题,因为每个查询只进行一次转换。表上有 6 个索引,但列 last_read 未涉及或包含在其中任何一个中。PK 在 book_id 上,没什么特别的。

估计的执行计划告诉我:

UPDATE: 0%
Clustered Index Update (on the PK constraint): 100%
Run Code Online (Sandbox Code Playgroud)

我不希望查询更新任何索引,因为 last_read 没有以任何方式编入索引,并且 book_id 没有更改。

我错过了什么?

Aar*_*and 5

让我们做一个小小的思考练习:

  1. 你认为 SQL Server 如何找到带有那个的行book_id
  2. 您认为它如何找到(而不是更新) 的值last_read

请记住,聚集索引是表。如果更新表,则必须至少更新聚集索引。

让我通过提出一个不同的问题来继续思考练习 - 您认为有(或应该)比通过聚集索引查找行并在那里更改值更有效的更新此值的方法吗?

让我们暂时不讨论这个问题,但那里的概念是相似的。