带覆盖列的SQL索引更新

时间:2014-06-25 14:52:47

标签: sql sql-server

我在表上创建索引,我想要包含一个覆盖列:messageText nvarchar(1024)

插入后,messageText永远不会更新,因此它是包含在覆盖索引中以加速查找的理想候选者。

但是如果我更新同一索引中的其他列会怎样?

索引中的整行是否需要重新分配,还是只更新索引中的数据?

简单示例

对下表进行成像:

CREATE TABLE [Messages](
    [messageID] [int] IDENTITY(1,1) NOT NULL,
    [mbrIDTo] [int] NOT NULL,
    [isRead] [bit] NOT NULL,
    [messageText] [nvarchar](1024) NOT NULL
)

以下索引:

CREATE NONCLUSTERED INDEX [IX_messages] ON [Messages] ( [mbrIDTo] ASC, [messageID] ASC ) 
INCLUDE ( [isRead], [messageText])

当我们更新表格时:

UPDATE    Messages
SET       isRead = 1
WHERE     (mbrIDTo = 6546)

查询计划显示索引IX_messages已被使用,并且还将更新,因为列isRead是索引的一部分。

因此,在索引中包含大型文本字段(例如上面的messageText)作为索引覆盖列的一部分,当同一索引中的其他值更新时会影响性能吗?

1 个答案:

答案 0 :(得分:1)

在SQL Server中更新行时,将删除整行,并插入包含更新记录的新行。因此,即使messageText字段没有改变,它仍然必须重新写入磁盘。

以下是Paul Randall撰写的一篇博文,其中有一个很好的例子:http://www.sqlskills.com/blogs/paul/do-changes-to-index-keys-really-do-in-place-updates/