Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 单列或多列主键的SQL Server性能差异?_Sql Server_Performance_Primary Key - Fatal编程技术网

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

Sql server 单列或多列主键的SQL Server性能差异?,sql-server,performance,primary-key,Sql Server,Performance,Primary Key,如果主键是单列(例如,为每行生成的GUID)或多列(例如,外键GUID+偏移量编号),则表的性能(在插入/更新和查询方面)是否有任何差异 如果有多列主键的话,我会假设查询速度应该更快,但是我会想象由于更复杂的唯一检查,插入速度会更慢?我还认为多列主键的数据类型也很重要(例如,如果其中一列是DateTime类型,则会增加复杂性)。这些只是我的想法,希望能引起回答和讨论,并不是基于事实的 我知道还有其他内容涉及这个主题,但我想知道的是性能影响,而不是管理/业务问题。这取决于您的访问模式、读/写比率以

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

如果有多列主键的话,我会假设查询速度应该更快,但是我会想象由于更复杂的唯一检查,插入速度会更慢?我还认为多列主键的数据类型也很重要(例如,如果其中一列是DateTime类型,则会增加复杂性)。这些只是我的想法,希望能引起回答和讨论,并不是基于事实的


我知道还有其他内容涉及这个主题,但我想知道的是性能影响,而不是管理/业务问题。

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

经验法则是使主键尽可能小(32位int),并在可能的情况下在单调递增的键上定义聚集索引(想想标识),除非您有范围搜索,它形成了针对该表的大部分查询

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

  • 将删除所有非聚集索引 包含聚集索引键,因此将更大。如果存在许多NC索引,这可能会对性能产生负面影响

  • 除非您使用的是“订购” GUID(例如梳或使用 NEWSEQUENTIALID()),您的插入 将随着时间的推移对索引进行分段。这意味着 你需要一个常规的索引和重建 可能会增加 页面中剩余的可用空间(填充 (系数)


  • 因为有很多因素在起作用(硬件、访问模式、数据大小),我建议您运行一些测试,并对特定情况进行基准测试。

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

    与键中组件的数量相比,键的(每个)组件(a)可变长度和(b)宽度[宽而不是窄列]对您的影响更大。除非微软在最新版本中再次打破它(他们在2005年打破了堆)。数据类型不会减慢速度;宽度,特别是可变长度(任何数据类型)不需要。请注意,如果将fixed len列设置为Nullable,则该列将变为变量。索引中的变量len列是个坏消息,因为每次访问都必须执行一点“解包”,才能获取数据

    显然,要使索引列尽可能窄,只使用固定列,而不是空列

    就复合键中的列数而言,一列肯定比七列快,但不会太多:三个胖宽变量列比七个瘦固定列慢得多

    GUID当然是一个非常胖的键;GUID加上其他任何东西都是非常非常胖的;GUID可为空是吉尼斯材料。不幸的是,这是解决身份问题的下意识反应,而身份问题又是没有选择好的自然关系键的结果。因此,最好在源代码处修复真正的问题,并选择好的自然关键点;避免认同;避免使用GUID


    体验和性能调整,而不是猜测。

    如果您的情况是面向更高数量的插入,那么占用空间越小越好

    有两件事需要分开,一是数据库级别的主键概念,二是应用程序使用的键概念

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

    如果是这种情况,那么我的建议是标识后跟guid。标识上的聚集索引,GUID上的唯一非聚集索引。如果使用GUID作为聚集索引,则数据插入将无处不在。这意味着数据不会按顺序插入,这会导致性能问题,因为系统会随机插入和移动页面


    将你的数据插入到一个有序的阵营中,这要感谢你的身份,这是一个好办法。您可以将排序留给索引结构(包含GUID的非结式唯一结构),这是一种比使用表数据更高效的排序结构。

    我的情况是,读很少,写速度比读速度更关键(尽管读速度仍然需要确定!).顺便说一句,我不是落选者,但谢谢你提供的额外信息。我正处于新DB设计的早期阶段,因此很难进行一些基准测试/测试。我希望获得一些其他的经验来帮助决定做什么。我会考虑你的意见,谢谢:)也不是“落选者”。你的陈述是正确的,但你的结论是错误的。例如,对于GUID,其思想是有目的地获得接近“随机”的密钥,从而获得分布式插入(避免下一个后续热点);因此,必须使用填充因子。我会投你反对票。如果你为预期的[GUID或其他随机]插入正确设置了fillfactor,CI将不会被分割,你也不需要常规的索引“重建”。我确实说过“你的STTMT是正确的,但是……”我知道GUID的原因,那只是其中之一,不是主要的。唉。评论的长度是有限制的。到目前为止,你是对的,我是对的。是的,当然还有很多,但是讨论需要更多的互动。我很感激你和我