好的。我到处读过有关 SQL Server 堆的内容,但没有什么太明确的内容可以真正指导我。我将尝试衡量性能,但希望得到一些关于我应该研究的内容的指导。这是 SQL Server 2008 企业版。以下是表格:
工作
- JobID(PK、GUID、外部生成)
- 开始日期(日期时间2)
- 帐户 ID
- 更多的会计字段,主要是小数和大整数
作业步骤
- JobStepID(PK、GUID、外部生成)
- 职位 ID FK
- 开始日期
- 更多的会计字段,主要是小数和大整数
用法:大量插入(数百次/秒),通常每个作业 1 个 JobStep。估计每月可能有 100-200M 行。根本没有更新,唯一删除的是 3 个月以上的存档数据。
每秒对数据执行大约 10 次查询。有的将JobSteps加入到Jobs中,有的只是看Jobs。几乎所有查询都会在 StartDate 范围内进行,其中大多数包括 AccountId 和一些其他会计字段(我们对它们有索引)。查询非常简单 - 执行计划的最大部分是 JobSteps 的连接。
优先考虑的是插入性能。对于数据出现在查询中的延迟(5 分钟左右)是可以容忍的,因此复制到其他服务器并在它们上运行查询当然是允许的。
除了将 JobSteps 加入到作业之外,基于 GUID 的查找非常罕见。
当前设置:无聚集索引。唯一看起来像是候选者的是 StartDate。但是,它并没有完美地增加。作业可以插入开始日期后 3 小时内的任何位置。这可能意味着以非最终顺序插入一百万行。
使用我当前的索引,1 个 Job + 1 个 JobStepId 的数据大小约为 500 字节。
问题:
这是堆的一个很好的用途吗?
当 StartDate 几乎是非连续的大约 2 小时/100 万行时,集群对 StartDate 有何影响?我的猜测是不断的重新排序会破坏插入性能。
我是否应该添加 bigint PK 只是为了拥有更小且始终增加的 key ? (我仍然需要查找指南。)
我读到GUIDs as PRIMARY KEYs and/or the clustering key ,这似乎表明即使发明一个键也会在其他索引上节省大量空间。另外,一些资源表明堆通常存在某种性能问题,但我不确定这是否仍然适用于 SQL 2008。
再说一遍,是的,我将尝试进行性能测试和测量。我只是想获得一些指导或其他文章的链接,以便我可以就要考虑的路径做出更明智的决定。
最佳答案
是的,堆有问题。您的数据在逻辑上会在整个节目中碎片化,并且无法简单地进行碎片整理。
想象一下将所有电话簿扔进一个桶中,然后尝试查找“鲍勃·史密斯”。或者使用带有姓氏、名字聚集索引的传统电话簿。
维护索引的开销是微不足道的。
StartDate 除非唯一,否则不是一个好的选择。聚集索引要求非聚集索引具有内部唯一性。如果没有声明唯一,SQL Server 将添加一个 4 字节的“唯一符”。
是的,我会使用 int 或 bigint 来使其更容易。至于 GUID:请参阅屏幕右侧的问题。
编辑:
注意,PK 和聚集索引是两个独立的问题,即使 SQL Server 默认会使 PK 聚集。
关于sql - 唯一标识符 PK : Is a SQL Server heap the right choice?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1286643/