MS-SQL何时维护表索引?

Ada*_*rth 7 sql-server indexing query-performance

为了论证,让我们说它适用于SQL 2005/8.我知道当您在表上放置索引来调整SELECT语句时,这些索引需要在INSERT/ UPDATE/ DELETEactions 期间进行维护.

我的主要问题是:

SQL Server何时维护表的索引?

我有很多后续问题:

我天真地假设它会在命令执行后执行.假设您要插入20行,它将在插入和提交20行后维护索引.

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

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

我已经看到了在大/多INSERT/ UPDATE动作之后删除索引并重新创建的情况.

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

  • 尝试整理INSERTUPDATE操作到更大的批处理中是否会有性能优势,例如通过收集要插入临时表的行,而不是执行许多较小的插入?

  • 如何将上面的行进行整理以防止丢弃索引而不是维护命中?

抱歉问题激增 - 这是我一直都知道的事情,但在尝试调整脚本以获得平衡时,我发现我实际上并不知道索引维护何时发生.

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

  • 一个索引重表调整选择.
  • 索引灯表(PK).

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

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

谢谢.

A-K*_*A-K 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;
Run Code Online (Sandbox Code Playgroud)