[英]Should SQL Server transaction tables always have a surrogate primary key
对于已经拥有主键(4列的自然复合键)的大型事务表(1亿行,20 GB),它是否有助于性能添加标识列并使其成为主键?
当前的主键(4列的自然复合主键)完成了这项工作,但我被告知你应该总是有一个代理键。 那么,可以通过创建标识列并将其作为主键来提高性能吗?
我正在使用SQL Server 2008 R2数据库。
编辑:此事务表主要连接到定义表并用于填充报表。
编辑:如果我确实添加了代理键,它将不会在任何联接中使用。 将使用现有的关键字段。
编辑:此表中没有子表
只需添加IDENTITY列并为其添加新约束和索引,就不太可能提高性能。 该表将更大,因此扫描和搜索可能需要更长时间。 还会有更多索引要更新。 当然,这完全取决于您测量的性能......以及在添加新列时是否打算对代码或数据库进行其他更改。 添加IDENTITY列而不执行任何其他操作可能是不明智的。
除非:
在每种情况下,表的PK(假定聚集)将在每个子条目/ NC条目中。 因此,使群集密钥更窄将受益。
如果您只有非NC索引(可能是一个)而且没有子表,那么您将实现的是
...但是你仍然需要对当前4列的索引/约束=空间增加。
如果您的4路键也捕获父表键(听起来很可能),那么您将失去重叠的优势。 但是,这将由新的索引/约束覆盖。
所以不,你可能不想这样做。
我们在一个十亿+行表上丢弃了一个代理键(bigint)并转移到实际的11向键并减少了65%以上的磁盘空间,因为结构更简单(索引减少一些,每页略多行等)
鉴于您的编辑以及问题引发的所有对话,我建议在此表中添加IDENTITY列会造成更多的伤害而不是收益。
---编辑:基于对问题的编辑,添加身份/代理键可能不是此问题的解决方案。
- 原始答案。
性能改进的一个例子是当你使用连接和有子表时。
在没有代理键的情况下,您必须将所有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列连接快得多)并且加入的代码通常也更快。 然而,另一方面,拥有至关重要的四个字段可能意味着不经常需要连接。 插入性能稍微受到影响,并且必须生成代理键并编制索引。 通常情况下,这是一个非常小的打击,但是可能性存在。
四列自然键通常不是唯一的,因为您认为这将是数据随时间变化的列数。 虽然它现在是独一无二的,但它会随着时间的推移而独一无二 如果您使用了代理键和一个唯一索引onteh自然键,并且后来证明不是唯一的,那么您所要做的就是删除唯一索引。 如果它是PK并且有子表,则必须完全重新设计数据库。
只有您可以决定哪些因素影响您的特定数据需求,代理键对某些应用程序更好,对其他应用程序则更糟。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.