我知道使用Identity列作为主键的问题。我想我第一次在Brent Ozar的博客上看过它。基本上,最常访问的数据是最近输入的数据,并且随着标识列的递增,这往往会将所有数据库活动集中在数据库的最后一页上,从而导致大量争用和锁定。建议您的主键基于一些有意义的列(或列),以便数据在数据库的页面中更均匀地传播。
鉴于此,我正在尝试优化主键:
Request_ID int --1234, 2326, etc
Department nchar(2) -- 'MP', 'SS', 'FR', etc
Condition_ID int identity
Condition_ID是必需的,因为(Request_ID + Department)不是唯一的。 (Request_ID + Department)中可以有多个条件。
Condition_ID是唯一的(作为标识列),但仅使其成为主键会导致我上面提到的问题。 Request_ID虽然不是标识列,但仍然是序列号,也会导致同样的问题。
部门至少是变化的(FR,SS,MP,CS等)
所以,我的问题是:鉴于我必须使用什么,什么是一个好的主键组合,以避免我提到的问题?
将部门作为PK中的第一列,然后是Request_ID,然后是Condition_ID会有什么好处吗?
答案 0 :(得分:0)
在Oracle中,您可以通过对索引进行散列分区来减少争用。例如,64的散列大小提供了一个很好的中间地带(A)相同块中的所有新行(争用太多)和(B)遍布整个地方的新行(物理I / O太多)。 / p>
你可以通过使用两个增量数字来做类似的事情。也就是说,计算mod(sequence1,64)并将其预先添加到sequence2,通过使用两列PK或通过乘法 -
class Resource {
//whatever members are necessary
public:
//resource acquisition for which this object is responsible should be constrained to constructor(s)
~Resource() { //or virtual ~Resource() if inheritance desired
//deal with resource cleanup
}
};
此外,除非你的桌子有很多插入,否则这个争论虽然真实,但你可能不会担心这个问题。
答案 1 :(得分:0)
以便数据在数据库页面中更均匀地传播
因此,您可以识别将影响性能的主键属性。
什么是一个好的主键组合......?
根据您的数据大小,您提到的密钥组合,您是否看到任何性能差异?如果是这样,有多重要?最终,你必须根据你的应用程序对大小,速度,负载以及Bogdan Sahlean,Martin Smith和Dan Guzman在上述评论中提出的其他特征的需求找到合适的组合。
将部门作为PK中的第一列,然后是Request_ID,然后是Condition_ID会有什么好处吗?
取决于查询和数据大小。 PK选择将影响数据的存储方式,从而无需制作单独的索引,因为您可以根据PK获得聚集索引(免费)。
增量键是否与聚合键相同?
没有。如果您说的是SQLSERVER,则incremental是指添加,删除记录时服务器为该字段管理的自动增量值。聚合键是指形成该行的聚合键的列值的组合(通常用于唯一性)。在您的示例中,所有这些聚合都是唯一的(因此是PK /群集的候选者):
Condition_ID
Condition_ID + Department
Condition_ID + Department + Request_ID