SQL Server事务表是否应始终具有代理主键

时间:2011-06-27 13:42:56

标签: sql-server database sql-server-2008 database-design

对于已经拥有主键(4列自然复合键)的大型事务表(1亿行,20 GB),它是否有助于提高性能列并将其作为主键?< / p>

当前主键(4列的自然复合主键)完成工作,但我被告知您应始终拥有代理键​​。 那么,可以通过创建标识列并将其作为主键来提高性能吗?

我正在使用SQL Server 2008 R2数据库。

编辑:此事务表主要连接到定义表并用于填充报表。

编辑:如果我确实添加了代理键,则不会在任何联接中使用它。将使用现有的关键字段。

编辑:此表中没有子表

5 个答案:

答案 0 :(得分:3)

只需添加IDENTITY列并为其添加新约束和索引,就不太可能提高性能。该表将更大,因此扫描和搜索可能需要更长时间。还会有更多索引要更新。当然,这完全取决于您测量的性能......以及在添加新列时是否打算对代码或数据库进行其他更改。添加IDENTITY列并不执行任何其他操作可能是不明智的。

答案 1 :(得分:2)

仅限于:

  • 你有更大的子表
  • 您有非聚集索引

在每种情况下,表格的PK(假定聚集)将在每个子条目/ NC条目中。因此,使群集密钥更窄将受益。

如果您只有非NC索引(可能是一个)而且没有子表,那么您将实现

  • 更宽的行(使用更多数据页)
  • 略小的B树(占总空间的一小部分)

...但是你仍然需要对当前4列的索引/约束=空间增加。

如果您的4路键也捕获父表键(听起来很可能),那么您将失去重叠的优势。但是,这将由新的索引/约束覆盖。

所以不,你可能不想这样做。

我们在十亿+行表上丢弃了一个代理键(bigint)并转移到实际的11路密钥并减少了65%以上的磁盘空间,因为结构更简单(索引少一个,每页略多行)等)

答案 2 :(得分:2)

鉴于您的编辑以及问题引发的所有对话,我建议在此表中添加IDENTITY列会造成更多的伤害而不是受益。

答案 3 :(得分:1)

<强> ---编辑: 根据对问题的编辑,添加身份/代理键可能不是解决此问题的方法。

- 原始答案。

性能改进的一个例子是当您使用连接时和有子表时。

如果没有代理键,则必须将所有th4 4个键复制到子表并加入4列。

t_parent
-------------
col1,
col2,
col3,
col4,
col5,
constraint pk_t_parent primary key (col1,col2,col3,col4)

t_child
----------
col1,
col2,
col3,
col4,
col7,
col8,
constraint pk_t_child primary key (col1,col2,col3,col4, col5),
constraint fk_parent_child foreign key (col1, col2, col3, col4) references
                                 t_parent ((col1, col2, col3, col4))

联接将包括所有4列..

select t2.*
  from t_parent t1, t_child t2
  where (t1.col1 = t2.col1 and 
         t1.col2 = t2.col2 and 
         t1.col3 = t2.col3 and 
         t1.col4 = t2.col4
        )

如果您使用代理键并在4列(现在是主键的一部分)上创建唯一约束,那么它将既有效又可以像以前一样验证数据。

答案 4 :(得分:1)

性能受损的一个地方是自然键中数据的变化。然后,改变必须公布给所有儿童记录。例如,假设其中一个字段是公司名称,公司更改了名称,然后所有相关记录,可能有数百万个,必须更改,但如果您使用代理键,则只需要一个记录更改。整数连接往往更快(通常比4列连接快得多)并且加入的代码通常也更快。然而,另一方面,拥有至关重要的四个字段可能意味着不经常需要连接。插入性能稍微受到影响,并且必须生成代理键并编制索引。通常情况下,这是一个非常小的打击,但是可能性存在。

四列自然键通常不是唯一的,因为您认为这将是数据随时间变化的列数。虽然它现在是独一无二的,但它会随着时间的推移而独一无二如果您使用了代理键和一个唯一索引onteh自然键,并且后来证明不是唯一的,那么您所要做的就是删除唯一索引。如果它是PK并且有子表,则必须完全重新设计数据库。

只有您可以决定哪些因素会影响您的特定数据需求,代理键对某些应用程序更好,对其他应用程序则更糟。