非聚集索引插入


10

说我有一张这样的桌子:

create table SomeTable
(
    id int identity(1, 1) not null primary key clustered,
    SomeString1 varchar(50) not null,
    SomeString2 varchar(50) not null
)
go

create nonclustered index IX_SomeString1
on SomeTable(SomeString1)
go

如果我要这样做:

insert into SomeTable(SomeString1, SomeString2)
values('foo', 'bar')
go

并且查看实际的执行计划,我只看到一个聚集索引插入。为什么在执行计划中看不到非聚集索引插入


我猜是因为直到您达到某个基数和行数阈值,才需要维护非聚集索引的统计信息。如果表中只有一行,则优化器会知道它不会使用该索引,因此不会维护该索引。
JNK 2012年

@JNK但是,如果我执行了select * from SomeTable where String1 = 'foo',那么我看到查询优化器确实IX_SomeString1为索引搜索选择了索引。因此,它必须更新该索引,不是吗?

1
您可以查看其统计信息并查看。在执行计划显示中也可能是一个缺点。您检查过xml吗?
JNK 2012年

1
SQL Server可以使用广泛或狭窄的计划,具体取决于受影响的行数。这控制着索引维护操作是单独发生还是在计划中显示为单独的操作,还是一起显示并在CI操作中显示。
马丁·史密斯

1
@MartinSmith很好的解释,我不知道。感谢您的链接和评论。我相信那应该是一个答案。

Answers:


9

对于单行插入,您可以获得狭窄/每行的计划

INSERT INTO SomeTable(SomeString1, SomeString2)
SELECT TOP 1 type, type
FROM master..spt_values

缩小计划

如果选择“聚集索引插入运算符”并查看“属性”窗口,则可以看到与XML中所示相同的信息。

属性窗口

如果您尝试1,000行

INSERT INTO SomeTable(SomeString1, SomeString2)
SELECT TOP 1000 type, type
FROM master..spt_values

您将获得不同的广泛/按索引计划,并分别拆分操作

广泛计划

有关这两者的更多信息,请参见宽计划与窄计划Craig Freedman的博客


6

永远不要相信图形计划显示,仅适用于新手。专业人员总是看XML。NC操作就在这里:

<Update DMLRequestSort="false">
  <Object Database="[testdb]" Schema="[dbo]" Table="[SomeTable]" Index="[PK__SomeTabl__3213E83F4AAF1C98]" IndexKind="Clustered" />
  <Object Database="[testdb]" Schema="[dbo]" Table="[SomeTable]" Index="[IX_SomeString1]" IndexKind="NonClustered" />

5
我不会说很长一段时间是“仅适用于新手”。
戴夫·马克勒2012年

我的“ newb”评论与观看者的技能无关,而是与体验有关:那些被平面图的自由“疏漏”所烧毁的人比相信它更了解。这更适用于死锁图
Remus Rusanu 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.