2010-09-21 34 views
7

出于参数的原因,可以说它适用于SQL 2005/8。我知道,当您将索引放在表格上以调整SELECT语句时,这些索引需要在执行/UPDATE/DELETE操作期间保留。MS-SQL何时维护表索引?

我的主要问题是:

如果将SQL Server的维护表的索引?

我有很多后续问题:

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

  • 在一个 脚本特性为多条语句 对表的情况下,会发生什么,但在其他方面 不同的语句?

  • 服务器是否具备智能 所有 语句执行后维持索引或它做 它每次发言?

我在哪里见过索引后,大型删除和重建情况/多INSERT/UPDATE行动。

  • 这大概即被重建 整个表的索引,即使你只 行更改了一把?

  • 会不会有在试图整理INSERTUPDATE行动统一到一个更大的批次性能优势 , 说,通过收集排在 临时表中插入,而不是做 许多较小的刀片?

  • 如何整理上面的堆,以防止删除索引与维护命中?

对不起,问题越来越多 - 这是我一直知道要注意的事情,但是当尝试调整脚本以获得平衡时,我发现实际上我并不知道索引维护何时发生。

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

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

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

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

谢谢。

+0

好问题。对于第二部分,它将完全依赖于索引的数量和内容,以确定是否更快地删除和重建,或只是在索引之上更新。与SQL中的大多数事情一样,100%的时间都没有正确的答案或方法。 – JNK 2010-09-21 15:09:49

+0

@JNK我推测,我希望有人可以将这种情况放在一边,或者解释某种方法开始变得昂贵的情况。 – 2010-09-21 15:11:16

回答

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; 
+0

我会认为数据完整性不适用于索引。这是唯一的情况下的唯一约束? – 2010-09-21 15:16:16

+0

如果索引不具有完整性,则几乎没有用处。我不确定如果SQL使用索引来查找应该存在的记录,但该记录不是,会发生什么情况。我猜你会得到错误的否定结果,这几乎违背了ACID的目的。 – JNK 2010-09-21 15:20:19

+0

因此,在插入/更新值时,索引是按行保留的?也就是说,他们会根据任何指标自动登陆到正确的位置,并且在需要时修改索引?所以即使行插入在一起,与多个较小的插入应该没有明显的区别?来想一想,我想有承诺索引更改和表锁定的开销... – 2010-09-21 15:22:24