7

为了争论,假设它是针对 SQL 2005/8 的。我了解当您在表上放置索引以调整SELECT语句时,这些索引需要在INSERT//操作期间维护UPDATEDELETE

我的主要问题是:

SQL Server 何时维护表的索引?

我有很多后续问题:

我天真地假设它会在命令执行后这样做。假设您要插入 20 行,它会在插入并提交 20 行后维护索引。

  • 如果脚本具有针对表的多个语句,但在其他方面是不同的语句,会发生什么情况?

  • 服务器是否具有在执行所有语句后维护索引的智能,还是每个语句都执行此操作?

我见过在大型/许多INSERT/UPDATE操作之后删除并重新创建索引的情况。

  • 即使您只更改少数行,这可能会导致重建整个表的索引?

  • 与进行许多较小的插入相比,尝试整理INSERTUPDATE操作成更大的批次(例如通过收集行以插入到临时表中)是否会带来性能优势?

  • 如何整理上面的行以防止删除索引而不是进行维护?

很抱歉问题泛滥 - 这是我一直都知道要注意的事情,但是在尝试调整脚本以获得平衡时,我发现我实际上不知道何时进行索引维护。

编辑:我知道性能问题很大程度上取决于插入/更新期间的数据量和索引数量。再次为了争论,我有两种情况:

  • 为选择调整的索引重表。
  • 索引灯台 (PK)。

这两种情况都会有一个大的插入/更新批次,比如 10k+ 行。

编辑 2:我知道能够在数据集上分析给定脚本。但是,分析并不能告诉我为什么给定的方法比另一种更快。我对索引背后的理论以及性能问题的根源更感兴趣,而不是确定的“这比那个更快”的答案。

谢谢。

4

1 回答 1

3

当您的声明(甚至不是交易)完成时,您的所有索引都是最新的。当您提交时,所有更改都将成为永久性的,并且所有锁都将被释放。否则就不是“智能”,它会违反完整性并可能导致错误。

编辑:“完整性”我的意思是:一旦提交,数据应该立即可供任何人使用。如果此时索引不是最新的,则有人可能会得到不正确的结果。

当您增加批量大小时,您的性能最初会提高,然后会变慢。您需要运行自己的基准测试并找出最佳批量大小。同样,您需要进行基准测试以确定删除/重新创建索引是否更快。

编辑:如果您在一个语句中插入/更新/删除成批的行,则每个语句都会修改一次索引。以下脚本演示了这一点:

CREATE TABLE dbo.Num(n INT NOT NULL PRIMARY KEY);
GO
INSERT INTO dbo.Num(n)
SELECT 0
UNION ALL
SELECT 1;
GO
-- 0 updates to 1, 1 updates to 0
UPDATE dbo.Num SET n = 1-n;
GO
-- doing it row by row would fail no matter how you do it
UPDATE dbo.Num SET n = 1-n WHERE n=0;
UPDATE dbo.Num SET n = 1-n WHERE n=1;
于 2010-09-21T15:11:40.377 回答