Sql server 聚集索引对数据库性能的影响

Sql server 聚集索引对数据库性能的影响,sql-server,database-design,indexing,sql-server-2000,Sql Server,Database Design,Indexing,Sql Server 2000,我最近参与了一个新的软件项目,该项目使用SQLServer2000作为数据存储 在查看该项目时,我发现其中一个主表在其主键上使用了聚集索引,该主键由四列组成: Sequence numeric(18, 0) Date datetime Client varchar(9) Hash tinyint 此表在正常操作过程中经历了大量插入 现在,我是C++开发人员,不是dB管理员,但我对这个表设计的第一印象是,将这些字段作为聚集索引对插入性能非常不利,因为数据必须在每个插入

我最近参与了一个新的软件项目,该项目使用SQLServer2000作为数据存储

在查看该项目时,我发现其中一个主表在其主键上使用了聚集索引,该主键由四列组成:

Sequence  numeric(18, 0)
Date      datetime
Client    varchar(9)
Hash      tinyint
此表在正常操作过程中经历了大量插入

现在,我是C++开发人员,不是dB管理员,但我对这个表设计的第一印象是,将这些字段作为聚集索引对插入性能非常不利,因为数据必须在每个插入件上物理重新排序。

此外,我看不出这有什么好处,因为必须经常查询所有这些字段才能证明聚集索引的合理性,对吗


因此,基本上,我需要一些弹药,以便在我走向权力机构时说服他们,表的设计应该改变。

聚集索引(CI)在不断增加的、狭窄的、很少变化的值上工作得最好。您希望您的CI涵盖在查询中使用>=,最多的列。您对SQL如何创建和使用索引有一些误解

聚集索引,至少不是实时的。它们只是一个逻辑顺序

我不希望基于此结构的性能受到重大影响,在您实际确定与该索引相关的性能问题之前删除聚集索引显然是过早优化

此外,索引可能很有用(尤其是其中包含多个字段的索引),即使对于没有对其中包含的所有列进行排序或查询的搜索也是如此

显然,创建一个由多部分组成的聚集索引应该是有道理的,就像任何索引一样,所以如果您认为它是随意添加的,那么请求它是有道理的


一句话:在实际检测到插入的性能问题之前,不要为插入性能优化索引。这通常是不值得的。

如果您的表上只有一个聚集索引,那可能不会太糟糕。但是,聚集索引还用于查找实际数据页中非聚集索引中的任何命中-因此,聚集索引(其所有列)也是表中每个非聚集索引的一部分

因此,如果您的表上有一些非聚集索引,那么您肯定是在a)浪费大量空间(不仅仅是在磁盘上,也在服务器的RAM中!),并且b)性能会很差

一个好的聚集索引应该是:

  • 小(最好的选择:4字节的INT)-你的非常糟糕,每个条目最多28字节
  • 独特的
  • 稳定(永不改变)
  • 日增
我敢打赌,您当前的设置至少违反了其中两项(如果不是更多的话)。不遵循这些建议会导致空间的浪费,正如你所说的,大量的页面和索引碎片和页面分割(当插入发生在聚集索引中间的某个地方时)必须“重新排列”数据。
老实说:只需在表中添加一个代理
ID INT-IDENTITY(1,1)
,并将其作为主集群键-如果您有大量的插入(和更新)操作,您应该会看到性能有很大的提升

有关什么是好的群集键以及它们的重要意义的更多背景信息,请参见:


聚集索引应包含查询次数最多的列,以便最大程度地查找或使非聚集索引覆盖查询中的所有列

主键和聚集索引不必相同。它们都是候选键,表通常有多个这样的键

你说

此外,我看不出这有什么好处,因为必须经常查询所有这些字段才能证明聚集索引的合理性,对吗

那不是真的。只需使用聚集索引的第一列或两列就可以进行搜索。这可能是一个范围搜索,但它仍然是一个搜索。您不必指定它的所有列来获得该好处。但是列的顺序确实很重要。如果您主要是在客户机上查询,那么序列列作为聚集索引中的第一列是一个错误的选择。第二列的选项应该是与第一列一起查询最多的项(而不是单独查询)。如果您发现第二列的查询频率几乎与第一列相同,那么非聚集索引将有所帮助

正如其他人所说,尽可能减少聚集索引中的列/字节数非常重要

序列是一个随机值而不是递增值,这太糟糕了,但这可能没有帮助。答案不是抛出标识列,除非应用程序可以开始将其用作此表的主要查询条件(不太可能)。现在,由于您被这个随机序列列所困扰(假定它是最常被查询的列),让我们看看您的另一个语句:

将这些字段作为聚集索引对插入性能非常不利,因为每次插入时都必须对数据进行物理重新排序

这并不完全正确

磁盘上的物理位置并不是我们在这里讨论的内容,但它确实在碎片方面发挥作用,这是一个性能方面的影响

每个8k页面内的行是未排序的。只是每页中的所有行都小于下一页,而大于上一页。当您插入一行且页面已满时,就会出现问题:您将得到页面拆分。引擎必须将插入行之后的所有行复制到新页面,这可以是