SQL Server与单列或多列主键的性能差异?

时间:2010-10-25 02:47:04

标签: sql-server performance primary-key

如果主键是单个列(例如,为每行生成的GUID)或多个列(例如,外键GUID),则表(在插入/更新和查询方面)性能是否存在任何差异? +偏移号码?

我会假设查询速度应该更快,如果有任何多列主键,但我会想象插入会更慢,因为一个稍微复杂的独特检查?我还想象多列主键的数据类型也很重要(例如,如果其中一列是DateTime类型,则会增加复杂性)。这些只是我想要调用答案的想法。讨论(希望!)并且不是基于事实的。

我意识到some其他questions涵盖了此主题,但我想知道性能影响而不是管理/业务问题。

4 个答案:

答案 0 :(得分:4)

密钥的(每个)组件将受到更多的影响:(a)可变长度和(b)宽度[宽而不是窄列],而不是密钥中的组件数。除非MS在最新版本中再次打破它(他们在2005年打破了Heaps)。数据类型不会减慢速度;宽度,特别是可变长度(任何数据类型)。请注意,如果将固定的len列设置为Nullable,则将其设置为可变列。索引中的变量len列是坏消息,因为必须在每次访问时执行一些“解包”以获取数据。

显然,使用固定列而不是Nullable列,尽可能缩小索引列。

就复合键中的列数而言,确保一列比七列快,但不是那么多:三个胖宽变量列比七个精简固定列慢得多。

GUID当然是一个非常肥胖的关键; GUID加上任何其他东西都非常胖; GUID Nullable是Guiness材料。不幸的是,它是解决IDENTITY问题的下意识反应,这反过来又是因为没有选择好的自然关系键。因此,建议您最好在源头修复真正的问题,并选择好的自然键;避免身份;避免GUID。

经验和性能调整,而非猜想。

答案 1 :(得分:1)

这取决于您的访问模式,读/写比率以及是否(可能最重要的)在主键上定义了聚簇索引。

经验法则是让主键尽可能小(32位int),并在可能的情况下在单调递增键(想象IDENTITY)上定义聚簇索引,除非您有范围搜索构成了大部分查询反对那张桌子。

如果您的应用程序是写密集型的,并且您在GUID列上定义聚簇索引,则应注意:

  1. 所有非聚集索引都将 包含聚簇索引键,因此会更大。如果有许多NC索引,这可能会对性能产生负面影响。

  2. 除非你使用'有序' GUID(例如COMB或使用 NEWSEQUENTIALID()),您的插入 将随着时间的推移分割索引。这意味着 你需要一个常规的索引重建和 可能增加的数量 页面中剩余的可用空间(填充 因子)

  3. 由于工作中有许多因素(硬件,访问模式,数据大小),我建议您运行一些测试并对您的特定情况进行基准测试。

答案 2 :(得分:0)

这取决于每种情况下的索引和存储。在所有其他条件相同的情况下,就性能而言,主键的选择是无关紧要的。索引和其他存储选项的选择将是决定性因素。

答案 3 :(得分:0)

如果您的情况将面向更多数量的刀片,则可能的尺寸越小越好。

您需要分离两件事,即数据库级主键的概念,以及应用程序使用的密钥的概念。

为什么需要GUID?您是要插入多个数据库服务器,然后将信息组合到一个集中式数据库中吗?

如果是这种情况,那么我的建议是一个身份,然后是一个guid。标识上的聚簇索引,以及GUID上的Unique Non聚簇。如果您将GUID用作聚簇索引,那么您的数据插入将遍布整个地方。这意味着您的数据不会按顺序插入,这会导致性能问题,因为系统会随机插入和移动页面。

由于身份的原因,您可以将数据插入有序的派系中,这是最佳选择。您可以将排序保留到索引结构(包含GUID的nonclusered唯一),这是一种比使用表数据更有效的排序结构。